X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsession.cc;h=914c6a9a77de28bd42aecf336841bf55e9f08609;hb=ae74d66eb79754ed2ce1416f4f57d827116af598;hp=da5f956c4bca67b13ec96520e1928e9c49078a94;hpb=f0247ebe6af7ed3429405ea242f9134ab63b5ffd;p=ardour.git diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index da5f956c4b..914c6a9a77 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -119,6 +119,7 @@ PBD::Signal1 > Session::AskAboutPlaylistDeletion PBD::Signal0 Session::Quit; PBD::Signal0 Session::FeedbackDetected; PBD::Signal0 Session::SuccessfulGraphSort; +PBD::Signal2 Session::VersionMismatch; static void clean_up_session_event (SessionEvent* ev) { delete ev; } const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event); @@ -132,12 +133,14 @@ Session::Session (AudioEngine &eng, : _engine (eng) , _target_transport_speed (0.0) , _requested_return_frame (-1) + , _under_nsm_control (false) , _session_dir (new SessionDirectory(fullpath)) , state_tree (0) , _state_of_the_state (Clean) , _butler (new Butler (*this)) , _post_transport_work (0) , _send_timecode_update (false) + , ltc_enc_buf(0) , _all_route_group (new RouteGroup (*this, "all")) , routes (new RouteList) , _total_free_4k_blocks (0) @@ -152,9 +155,7 @@ Session::Session (AudioEngine &eng, , _suspend_timecode_transmission (0) { _locations = new Locations (*this); -#ifdef HAVE_LTC ltc_encoder = NULL; -#endif if (how_many_dsp_threads () > 1) { /* For now, only create the graph if we are using >1 DSP threads, as @@ -232,6 +233,10 @@ Session::destroy () _state_of_the_state = StateOfTheState (CannotSave|Deletion); + /* disconnect from any and all signals that we are connected to */ + + drop_connections (); + _engine.remove_session (); /* deregister all ports - there will be no process or any other @@ -240,9 +245,7 @@ Session::destroy () Port::PortDrop (); /* EMIT SIGNAL */ -#ifdef HAVE_LTC ltc_tx_cleanup(); -#endif /* clear history so that no references to objects are held any more */ @@ -1077,7 +1080,7 @@ Session::set_auto_loop_location (Location* location) } if (location->end() <= location->start()) { - error << _("Session: you can't use a mark for auto loop") << endmsg; + error << _("You cannot use this location for auto-loop because it has zero or negative length") << endmsg; return; } @@ -1596,7 +1599,7 @@ Session::find_route_name (string const & base, uint32_t& id, char* name, size_t } ++id; - + } while (id < (UINT_MAX-1)); return false; @@ -1613,7 +1616,7 @@ Session::count_existing_track_channels (ChanCount& in, ChanCount& out) for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { boost::shared_ptr tr = boost::dynamic_pointer_cast (*i); - if (tr && !tr->is_hidden()) { + if (tr && !tr->is_auditioner()) { in += tr->n_inputs(); out += tr->n_outputs(); } @@ -1634,8 +1637,6 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost: RouteList new_routes; list > ret; - cerr << "Adding MIDI track with in = " << input << " out = " << output << endl; - bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("MIDI"); while (how_many) { @@ -1694,7 +1695,7 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost: catch (AudioEngine::PortRegistrationFailure& pfe) { - error << string_compose (_("No more JACK ports are available. You will need to stop %1 and restart JACK with ports if you need this many tracks."), PROGRAM_NAME) << endmsg; + error << string_compose (_("No more JACK ports are available. You will need to stop %1 and restart JACK with more ports if you need this many tracks."), PROGRAM_NAME) << endmsg; goto failed; } @@ -2008,6 +2009,8 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r bus->add_internal_return (); ret.push_back (bus); + + ARDOUR::GUIIdle (); } @@ -2035,12 +2038,13 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r } RouteList -Session::new_route_from_template (uint32_t how_many, const std::string& template_path) +Session::new_route_from_template (uint32_t how_many, const std::string& template_path, const std::string& name_base) { RouteList ret; uint32_t control_id; XMLTree tree; uint32_t number = 0; + const uint32_t being_added = how_many; if (!tree.read (template_path.c_str())) { return ret; @@ -2060,13 +2064,29 @@ Session::new_route_from_template (uint32_t how_many, const std::string& template node_copy.remove_property_recursively (X_("id")); try { - string const route_name = node_copy.property(X_("name"))->value (); - - /* generate a new name by adding a number to the end of the template name */ char name[32]; - if (!find_route_name (route_name.c_str(), ++number, name, sizeof(name), true)) { - fatal << _("Session: UINT_MAX routes? impossible!") << endmsg; - /*NOTREACHED*/ + + if (!name_base.empty()) { + + /* if we're adding more than one routes, force + * all the names of the new routes to be + * numbered, via the final parameter. + */ + + if (!find_route_name (name_base.c_str(), ++number, name, sizeof(name), (being_added > 1))) { + fatal << _("Session: UINT_MAX routes? impossible!") << endmsg; + /*NOTREACHDE*/ + } + + } else { + + string const route_name = node_copy.property(X_("name"))->value (); + + /* generate a new name by adding a number to the end of the template name */ + if (!find_route_name (route_name.c_str(), ++number, name, sizeof(name), true)) { + fatal << _("Session: UINT_MAX routes? impossible!") << endmsg; + /*NOTREACHED*/ + } } /* set this name in the XML description that we are about to use */ @@ -2135,6 +2155,31 @@ Session::new_route_from_template (uint32_t how_many, const std::string& template void Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save) +{ + try { + PBD::Unwinder aip (_adding_routes_in_progress, true); + add_routes_inner (new_routes, input_auto_connect, output_auto_connect); + + } catch (...) { + error << _("Adding new tracks/busses failed") << endmsg; + } + + graph_reordered (); + + update_latency (true); + update_latency (false); + + set_dirty(); + + if (save) { + save_state (_current_snapshot_name); + } + + RouteAdded (new_routes); /* EMIT SIGNAL */ +} + +void +Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect) { ChanCount existing_inputs; ChanCount existing_outputs; @@ -2191,6 +2236,7 @@ Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output } } + if (input_auto_connect || output_auto_connect) { auto_connect_route (r, existing_inputs, existing_outputs, true, input_auto_connect); } @@ -2199,9 +2245,9 @@ Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output reasonable defaults because they also affect the remote control ID in most situations. */ - + if (!r->has_order_key (EditorSort)) { - if (r->is_hidden()) { + if (r->is_auditioner()) { /* use an arbitrarily high value */ r->set_order_key (EditorSort, UINT_MAX); r->set_order_key (MixerSort, UINT_MAX); @@ -2212,34 +2258,23 @@ Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output order++; } } + + ARDOUR::GUIIdle (); } if (_monitor_out && IO::connecting_legal) { - - { - Glib::Threads::Mutex::Lock lm (_engine.process_lock()); - - for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) { - if ((*x)->is_monitor()) { - /* relax */ - } else if ((*x)->is_master()) { + Glib::Threads::Mutex::Lock lm (_engine.process_lock()); + + for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) { + if ((*x)->is_monitor()) { + /* relax */ + } else if ((*x)->is_master()) { /* relax */ - } else { - (*x)->enable_monitor_send (); - } + } else { + (*x)->enable_monitor_send (); } } - - resort_routes (); } - - set_dirty(); - - if (save) { - save_state (_current_snapshot_name); - } - - RouteAdded (new_routes); /* EMIT SIGNAL */ } void @@ -2437,7 +2472,7 @@ Session::route_listen_changed (void* /*src*/, boost::weak_ptr wpr) /* new listen: disable all other listen */ boost::shared_ptr r = routes.reader (); for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) { + if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner()) { continue; } (*i)->set_listen (false, this); @@ -2519,7 +2554,7 @@ Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_p /* new solo: disable all other solos, but not the group if its solo-enabled */ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden() || + if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() || (leave_group_alone && ((*i)->route_group() == rg))) { continue; } @@ -2539,7 +2574,7 @@ Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_p bool via_sends_only; bool in_signal_flow; - if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden() || + if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() || (leave_group_alone && ((*i)->route_group() == rg))) { continue; } @@ -2628,11 +2663,11 @@ Session::update_route_solo_state (boost::shared_ptr r) } for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) { + if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_auditioner() && (*i)->self_soloed()) { something_soloed = true; } - if (!(*i)->is_hidden() && (*i)->listening_via_monitor()) { + if (!(*i)->is_auditioner() && (*i)->listening_via_monitor()) { if (Config->get_solo_control_is_listen_control()) { listeners++; } else { @@ -3365,7 +3400,7 @@ Session::create_audio_source_for_session (size_t n_chans, string const & n, uint const string path = new_source_path_from_name(DataType::AUDIO, name); return boost::dynamic_pointer_cast ( - SourceFactory::createWritable (DataType::AUDIO, *this, path, string(), destructive, frame_rate())); + SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate())); } /** Return a unique name based on \a base for a new internal MIDI source */ @@ -3441,7 +3476,7 @@ Session::create_midi_source_for_session (Track* track, string const & n) return boost::dynamic_pointer_cast ( SourceFactory::createWritable ( - DataType::MIDI, *this, path, string(), false, frame_rate())); + DataType::MIDI, *this, path, false, frame_rate())); } @@ -3551,7 +3586,7 @@ Session::graph_reordered () from a set_state() call or creating new tracks. Ditto for deletion. */ - if (_state_of_the_state & (InitialConnecting|Deletion)) { + if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) { return; } @@ -3993,7 +4028,7 @@ Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end, try { fsource = boost::dynamic_pointer_cast ( - SourceFactory::createWritable (DataType::AUDIO, *this, buf, string(), false, frame_rate())); + SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate())); } catch (failed_constructor& err) { @@ -4186,7 +4221,7 @@ Session::add_automation_list(AutomationList *al) bool Session::have_rec_enabled_track () const { - return g_atomic_int_get (&_have_rec_enabled_track) == 1; + return g_atomic_int_get (const_cast(&_have_rec_enabled_track)) == 1; } /** Update the state of our rec-enabled tracks flag */ @@ -4531,7 +4566,7 @@ Session::update_latency (bool playback) { DEBUG_TRACE (DEBUG::Latency, string_compose ("JACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE"))); - if (_state_of_the_state & (InitialConnecting|Deletion)) { + if ((_state_of_the_state & (InitialConnecting|Deletion)) || _adding_routes_in_progress) { return; } @@ -4587,7 +4622,7 @@ Session::post_playback_latency () boost::shared_ptr r = routes.reader (); for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (!(*i)->is_hidden() && ((*i)->active())) { + if (!(*i)->is_auditioner() && ((*i)->active())) { _worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ()); } } @@ -4693,7 +4728,7 @@ Session::update_latency_compensation (bool force_whole_graph) boost::shared_ptr r = routes.reader (); for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (!(*i)->is_hidden() && ((*i)->active())) { + if (!(*i)->is_auditioner() && ((*i)->active())) { framecnt_t tl; if ((*i)->signal_latency () != (tl = (*i)->update_signal_latency ())) { some_track_latency_changed = true;