/* These are all static "per-class" signals */
- RegionFactory::CheckNewRegion.connect_same_thread (*this, boost::bind (&Session::add_region, this, _1));
SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
- Processor::ProcessorCreated.connect_same_thread (*this, boost::bind (&Session::add_processor, this, _1));
AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
}
int
-Session::second_stage_init (bool new_session)
+Session::second_stage_init ()
{
AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
- if (!new_session) {
+ if (!_is_new) {
if (load_state (_current_snapshot_name)) {
return -1;
}
_engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
try {
- when_engine_running (new_session);
+ when_engine_running ();
}
/* handle this one in a different way than all others, so that its clear what happened */
ControlProtocolManager::instance().set_session (this);
- config.set_end_marker_is_free (new_session);
+ config.set_end_marker_is_free (_is_new);
_state_of_the_state = Clean;
}
int
-Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
+Session::create (const string& mix_template, nframes_t initial_length, BusProfile* bus_profile)
{
if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
return -1;
}
- /* check new_session so we don't overwrite an existing one */
-
if (!mix_template.empty()) {
std::string in_path = mix_template;
if (out){
out << in.rdbuf();
-
- // okay, session is set up. Treat like normal saved
- // session from now on.
-
- new_session = false;
return 0;
} else {
_locations.add (end_location);
_state_of_the_state = Clean;
+
+ /* set up Master Out and Control Out if necessary */
+
+ if (bus_profile) {
+
+ RouteList rl;
+ int control_id = 1;
+ ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
+
+ if (bus_profile->master_out_channels) {
+ Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
+ if (rt->init ()) {
+ delete rt;
+ return -1;
+ }
+ boost_debug_shared_ptr_mark_interesting (rt, "Route");
+ boost::shared_ptr<Route> r (rt);
+ r->input()->ensure_io (count, false, this);
+ r->output()->ensure_io (count, false, this);
+ r->set_remote_control_id (control_id++);
+
+ rl.push_back (r);
+
+ if (Config->get_use_monitor_bus()) {
+ Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
+ if (rt->init ()) {
+ delete rt;
+ return -1;
+ }
+ boost_debug_shared_ptr_mark_interesting (rt, "Route");
+ boost::shared_ptr<Route> r (rt);
+ r->input()->ensure_io (count, false, this);
+ r->output()->ensure_io (count, false, this);
+ r->set_remote_control_id (control_id);
+
+ rl.push_back (r);
+ }
+
+ } else {
+ /* prohibit auto-connect to master, because there isn't one */
+ bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
+ }
+
+ if (!rl.empty()) {
+ add_routes (rl, false);
+ }
+
+ /* this allows the user to override settings with an environment variable.
+ */
+
+ if (no_auto_connect()) {
+ bus_profile->input_ac = AutoConnectOption (0);
+ bus_profile->output_ac = AutoConnectOption (0);
+ }
+
+ Config->set_input_auto_connect (bus_profile->input_ac);
+ Config->set_output_auto_connect (bus_profile->output_ac);
+ }
save_state ("");
sys::remove (xml_path);
}
+#ifdef HAVE_JACK_SESSION
+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());
+ }
+
+ jack_session_reply (_engine.jack(), event);
+
+ if (event->type == JackSessionSaveAndQuit) {
+ // TODO: make ardour quit.
+ }
+
+ jack_session_event_free( event );
+}
+#endif
+
int
Session::save_state (string snapshot_name, bool pending)
{
/* the sort should have put control outs first */
- if (_control_out) {
- assert (_control_out == public_order.front());
+ if (_monitor_out) {
+ assert (_monitor_out == public_order.front());
}
for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
boost::shared_ptr<Route>
Session::XMLRouteFactory (const XMLNode& node, int version)
{
+ boost::shared_ptr<Route> ret;
+
if (node.name() != "Route") {
- return boost::shared_ptr<Route> ((Route*) 0);
+ return ret;
}
- bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
+ const XMLProperty* dsprop;
+ if ((dsprop = node.property (X_("diskstream-id"))) == 0) {
+ dsprop = node.property (X_("diskstream"));
+ }
+
DataType type = DataType::AUDIO;
const XMLProperty* prop = node.property("default-type");
- boost::shared_ptr<Route> ret;
if (prop) {
- type = DataType(prop->value());
+ type = DataType (prop->value());
}
- assert(type != DataType::NIL);
+ assert (type != DataType::NIL);
- if (has_diskstream) {
- if (type == DataType::AUDIO) {
- AudioTrack* at = new AudioTrack (*this, node, version);
- boost_debug_shared_ptr_mark_interesting (at, "Track");
- ret.reset (at);
-
- } else {
- ret.reset (new MidiTrack (*this, node, version));
- }
+ if (dsprop) {
+
+ boost::shared_ptr<Diskstream> ds;
+ PBD::ID diskstream_id (dsprop->value());
+ PBD::ID zero ("0");
+
+ /* 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."
+ */
+
+ if (diskstream_id != zero) {
+
+ ds = diskstream_by_id (diskstream_id);
+
+ if (!ds) {
+ error << string_compose (_("cannot find diskstream ID %1"), diskstream_id.to_s()) << endmsg;
+ return ret;
+ }
+ }
+
+ Track* track;
+
+ 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 (ds) {
+ track->set_diskstream (ds);
+ } else {
+ track->use_new_diskstream ();
+ }
+
+ 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, node);
- boost_debug_shared_ptr_mark_interesting (rt, "Route");
- ret.reset (rt);
+ 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;
+ }
}
return ret;
if (str == "master") {
r = _master_out;
} else if (str == "control" || str == "listen") {
- r = _control_out;
+ r = _monitor_out;
} else {
r = route_by_name (desc.top_level_name());
}