#include "ardour/midi_track.h"
#include "ardour/named_selection.h"
#include "ardour/processor.h"
+#include "ardour/port.h"
#include "ardour/region_factory.h"
#include "ardour/route_group.h"
#include "ardour/send.h"
_non_soloed_outs_muted = false;
_listen_cnt = 0;
+ _solo_isolated_cnt = 0;
g_atomic_int_set (&processing_prohibited, 0);
_transport_speed = 0;
_last_transport_speed = 0;
transport_sub_state = 0;
_transport_frame = 0;
_requested_return_frame = -1;
- _session_range_location = new Location (0, 0, _("session"), Location::IsSessionRange);
+ _session_range_location = 0;
g_atomic_int_set (&_record_status, Disabled);
loop_changing = false;
play_loop = false;
have_looped = false;
_last_roll_location = 0;
+ _last_roll_or_reversal_location = 0;
_last_record_location = 0;
pending_locate_frame = 0;
pending_locate_roll = false;
session_send_mtc = false;
g_atomic_int_set (&_playback_load, 100);
g_atomic_int_set (&_capture_load, 100);
- g_atomic_int_set (&_playback_load_min, 100);
- g_atomic_int_set (&_capture_load_min, 100);
_play_range = false;
_exporting = false;
pending_abort = false;
ControlProtocolManager::instance().set_session (this);
- config.set_end_marker_is_free (_is_new);
-
_state_of_the_state = Clean;
+ Port::set_connecting_blocked (false);
+
DirtyChanged (); /* EMIT SIGNAL */
if (state_was_pending) {
}
int
-Session::create (const string& mix_template, nframes_t initial_length, BusProfile* bus_profile)
+Session::create (const string& mix_template, BusProfile* bus_profile)
{
if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
if (out){
out << in.rdbuf();
+ _is_new = false;
return 0;
} else {
/* set initial start + end point */
- _session_range_location->set (0, initial_length);
- _locations.add (_session_range_location);
-
_state_of_the_state = Clean;
/* set up Master Out and Control Out if necessary */
return 0;
}
-
-int
-Session::load_diskstreams (const XMLNode& node)
-{
- XMLNodeList clist;
- XMLNodeConstIterator citer;
-
- clist = node.children();
-
- for (citer = clist.begin(); citer != clist.end(); ++citer) {
-
- try {
- /* diskstreams added automatically by DiskstreamCreated handler */
- if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
- AudioDiskstream* dsp (new AudioDiskstream (*this, **citer));
- boost::shared_ptr<AudioDiskstream> dstream (dsp);
- add_diskstream (dstream);
- } else if ((*citer)->name() == "MidiDiskstream") {
- boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
- add_diskstream (dstream);
- } else {
- error << _("Session: unknown diskstream type in XML") << endmsg;
- }
- }
-
- catch (failed_constructor& err) {
- error << _("Session: could not load diskstream via XML state") << endmsg;
- return -1;
- }
- }
-
- return 0;
-}
-
void
Session::maybe_write_autosave()
{
void
Session::jack_session_event (jack_session_event_t * event)
{
- if (save_state ("jacksession_snap")) {
- event->flags = JackSessionSaveError;
- } else {
- sys::path xml_path (_session_dir->root_path());
- xml_path /= legalize_for_path ("jacksession_snap") + statefile_suffix;
-
- string cmd ("PROG_NAME -U ");
- cmd += event->client_uuid;
- cmd += " \"";
- cmd += xml_path.to_string();
- cmd += '\"';
-
- event->command_line = strdup (cmd.c_str());
- }
+ char timebuf[128];
+ time_t n;
+ struct tm local_time;
+
+ time (&n);
+ localtime_r (&n, &local_time);
+ strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
+
+ if (event->type == JackSessionSaveTemplate)
+ {
+ if (save_template( timebuf )) {
+ event->flags = JackSessionSaveError;
+ } else {
+ string cmd ("ardour3 -P -U ");
+ cmd += event->client_uuid;
+ cmd += " -T ";
+ cmd += timebuf;
+
+ event->command_line = strdup (cmd.c_str());
+ }
+ }
+ else
+ {
+ if (save_state (timebuf)) {
+ event->flags = JackSessionSaveError;
+ } else {
+ sys::path xml_path (_session_dir->root_path());
+ xml_path /= legalize_for_path (timebuf) + statefile_suffix;
+
+ string cmd ("ardour3 -P -U ");
+ cmd += event->client_uuid;
+ cmd += " \"";
+ cmd += xml_path.to_string();
+ cmd += '\"';
+
+ event->command_line = strdup (cmd.c_str());
+ }
+ }
jack_session_reply (_engine.jack(), event);
#endif
int
-Session::save_state (string snapshot_name, bool pending)
+Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
{
XMLTree tree;
sys::path xml_path(_session_dir->root_path());
/* tell sources we're saving first, in case they write out to a new file
* which should be saved with the state rather than the old one */
- for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
+ for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
i->second->session_saved();
+ }
tree.set_root (&get_state());
if (snapshot_name.empty()) {
snapshot_name = _current_snapshot_name;
- }
+ } else if (switch_to_snapshot) {
+ _current_snapshot_name = snapshot_name;
+ }
if (!pending) {
if (!state_was_pending) {
xmlpath = _session_dir->root_path();
- xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
+ xmlpath /= snapshot_name;
}
- if (!sys::exists (xmlpath)) {
- error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
- return 1;
- }
+ if (!sys::exists (xmlpath)) {
+ xmlpath = _session_dir->root_path();
+ xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
+ if (!sys::exists (xmlpath)) {
+ error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
+ return 1;
+ }
+ }
state_tree = new XMLTree;
}
}
- child = node->add_child ("DiskStreams");
-
- {
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if (!(*i)->hidden()) {
- child->add_child_nocopy ((*i)->get_state());
- }
- }
- }
-
if (full_state) {
node->add_child_nocopy (_locations.get_state());
} else {
// with the default start and end, and get the state for that.
Locations loc;
Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
- range->set (0, compute_initial_length ());
+ range->set (max_frames, 0);
loc.add (range);
node->add_child_nocopy (loc.get_state());
}
Locations
Sources
AudioRegions
- AudioDiskstreams
Connections
Routes
RouteGroups
set_auto_punch_location (location);
}
- if ((location = _locations.session_range_location()) == 0) {
- _locations.add (_session_range_location);
- } else {
+ if ((location = _locations.session_range_location()) != 0) {
delete _session_range_location;
_session_range_location = location;
}
- AudioFileSource::set_header_position_offset (_session_range_location->start());
+ if (_session_range_location) {
+ AudioFileSource::set_header_position_offset (_session_range_location->start());
+ }
if ((child = find_named_node (node, "Sources")) == 0) {
error << _("Session: XML state has no sources section") << endmsg;
}
}
- if ((child = find_named_node (node, "DiskStreams")) == 0) {
- error << _("Session: XML state has no diskstreams section") << endmsg;
- goto out;
- } else if (load_diskstreams (*child)) {
- goto out;
- }
-
if (version >= 3000) {
if ((child = find_named_node (node, "Bundles")) == 0) {
warning << _("Session: XML state has no bundles section") << endmsg;
goto out;
}
+ if (version < 3000) {
+ if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
+ error << _("Session: XML state has no diskstreams section") << endmsg;
+ goto out;
+ } else if (load_diskstreams_2X (*child, version)) {
+ goto out;
+ }
+ }
+
if ((child = find_named_node (node, "Routes")) == 0) {
error << _("Session: XML state has no routes section") << endmsg;
goto out;
goto out;
}
+ /* our diskstreams list is no longer needed as they are now all owned by their Route */
+ _diskstreams_2X.clear ();
+
if (version >= 3000) {
if ((child = find_named_node (node, "RouteGroups")) == 0) {
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
- boost::shared_ptr<Route> route (XMLRouteFactory (**niter, version));
-
+ boost::shared_ptr<Route> route;
+ if (version < 3000) {
+ route = XMLRouteFactory_2X (**niter, version);
+ } else {
+ route = XMLRouteFactory (**niter, version);
+ }
+
if (route == 0) {
error << _("Session: cannot create Route from XML description.") << endmsg;
return -1;
return ret;
}
- const XMLProperty* dsprop;
+ XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
- if ((dsprop = node.property (X_("diskstream-id"))) == 0) {
- dsprop = node.property (X_("diskstream"));
- }
-
DataType type = DataType::AUDIO;
const XMLProperty* prop = node.property("default-type");
assert (type != DataType::NIL);
- if (dsprop) {
-
- boost::shared_ptr<Diskstream> ds;
- PBD::ID diskstream_id (dsprop->value());
- PBD::ID zero ("0");
+ if (ds_child) {
- /* this wierd hack is used when creating
- tracks from a template. We have a special
- ID for the diskstream that means "you
- should create a new diskstream here, not
- look for an old one."
- */
+ Track* track;
- if (diskstream_id != zero) {
+ if (type == DataType::AUDIO) {
+ track = new AudioTrack (*this, X_("toBeResetFroXML"));
+
+ } else {
+ track = new MidiTrack (*this, X_("toBeResetFroXML"));
+ }
+
+ if (track->init()) {
+ delete track;
+ return ret;
+ }
+
+ if (track->set_state (node, version)) {
+ delete track;
+ return ret;
+ }
+
+ boost_debug_shared_ptr_mark_interesting (track, "Track");
+ ret.reset (track);
+
+ } else {
+ Route* rt = new Route (*this, X_("toBeResetFroXML"));
+
+ if (rt->init () == 0 && rt->set_state (node, version) == 0) {
+ boost_debug_shared_ptr_mark_interesting (rt, "Route");
+ ret.reset (rt);
+ } else {
+ delete rt;
+ }
+ }
- ds = diskstream_by_id (diskstream_id);
+ return ret;
+}
- if (!ds) {
- error << string_compose (_("cannot find diskstream ID %1"), diskstream_id.to_s()) << endmsg;
- return ret;
- }
- }
+boost::shared_ptr<Route>
+Session::XMLRouteFactory_2X (const XMLNode& node, int version)
+{
+ boost::shared_ptr<Route> ret;
+
+ if (node.name() != "Route") {
+ return ret;
+ }
+
+ XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
+ if (!ds_prop) {
+ ds_prop = node.property (X_("diskstream"));
+ }
+
+ DataType type = DataType::AUDIO;
+ const XMLProperty* prop = node.property("default-type");
+
+ if (prop) {
+ type = DataType (prop->value());
+ }
+
+ assert (type != DataType::NIL);
+
+ if (ds_prop) {
+
+ list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
+ while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
+ ++i;
+ }
+
+ if (i == _diskstreams_2X.end()) {
+ error << _("Could not find diskstream for route") << endmsg;
+ return boost::shared_ptr<Route> ();
+ }
Track* track;
return ret;
}
- if (ds) {
- track->set_diskstream (ds);
- } else {
- track->use_new_diskstream ();
- }
-
if (track->set_state (node, version)) {
delete track;
return ret;
}
+
+ track->set_diskstream (*i);
boost_debug_shared_ptr_mark_interesting (track, "Track");
ret.reset (track);
if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
/* auto-input only makes a difference if we're rolling */
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)->record_enabled ()) {
- (*i)->monitor_input (!config.get_auto_input());
+ boost::shared_ptr<RouteList> rl = routes.reader ();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && tr->record_enabled ()) {
+ tr->monitor_input (!config.get_auto_input());
}
}
}
{
_history.set_depth (d);
}
+
+int
+Session::load_diskstreams_2X (XMLNode const & node, int)
+{
+ XMLNodeList clist;
+ XMLNodeConstIterator citer;
+
+ clist = node.children();
+
+ for (citer = clist.begin(); citer != clist.end(); ++citer) {
+
+ try {
+ /* diskstreams added automatically by DiskstreamCreated handler */
+ if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
+ boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
+ _diskstreams_2X.push_back (dsp);
+ } else {
+ error << _("Session: unknown diskstream type in XML") << endmsg;
+ }
+ }
+
+ catch (failed_constructor& err) {
+ error << _("Session: could not load diskstream via XML state") << endmsg;
+ return -1;
+ }
+ }
+
+ return 0;
+}