diff options
-rw-r--r-- | gtk2_ardour/editor_drag.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/editor_group_tabs.cc | 6 | ||||
-rw-r--r-- | gtk2_ardour/editor_group_tabs.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/editor_ops.cc | 3 | ||||
-rw-r--r-- | gtk2_ardour/editor_routes.cc | 36 | ||||
-rw-r--r-- | gtk2_ardour/editor_routes.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/editor_selection.cc | 8 | ||||
-rw-r--r-- | gtk2_ardour/group_tabs.cc | 9 | ||||
-rw-r--r-- | gtk2_ardour/group_tabs.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/mixer_group_tabs.cc | 6 | ||||
-rw-r--r-- | gtk2_ardour/mixer_group_tabs.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/mixer_ui.cc | 63 | ||||
-rw-r--r-- | gtk2_ardour/mixer_ui.h | 3 | ||||
-rw-r--r-- | gtk2_ardour/port_group.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/route_ui.cc | 42 | ||||
-rw-r--r-- | libs/ardour/ardour/route.h | 18 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 5 | ||||
-rw-r--r-- | libs/ardour/ardour/types.h | 6 | ||||
-rw-r--r-- | libs/ardour/enums.cc | 5 | ||||
-rw-r--r-- | libs/ardour/route.cc | 131 | ||||
-rw-r--r-- | libs/ardour/route_graph.cc | 4 | ||||
-rw-r--r-- | libs/ardour/session.cc | 90 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 10 |
23 files changed, 268 insertions, 189 deletions
diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index ae3795f7fa..8ae618b37f 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -420,7 +420,7 @@ struct EditorOrderTimeAxisViewSorter { RouteTimeAxisView* ra = dynamic_cast<RouteTimeAxisView*> (a); RouteTimeAxisView* rb = dynamic_cast<RouteTimeAxisView*> (b); assert (ra && rb); - return ra->route()->order_key (N_ ("editor")) < rb->route()->order_key (N_ ("editor")); + return ra->route()->order_key (EditorSort) < rb->route()->order_key (EditorSort); } }; diff --git a/gtk2_ardour/editor_group_tabs.cc b/gtk2_ardour/editor_group_tabs.cc index 352eec88cc..5a1e9c8aaa 100644 --- a/gtk2_ardour/editor_group_tabs.cc +++ b/gtk2_ardour/editor_group_tabs.cc @@ -177,10 +177,10 @@ EditorGroupTabs::default_properties () const return plist; } -string +RouteSortOrderKey EditorGroupTabs::order_key () const { - return X_("editor"); + return EditorSort; } RouteList @@ -201,5 +201,5 @@ EditorGroupTabs::selected_routes () const void EditorGroupTabs::sync_order_keys () { - _editor->_routes->sync_order_keys (""); + _editor->_routes->sync_order_keys (UndefinedSort); } diff --git a/gtk2_ardour/editor_group_tabs.h b/gtk2_ardour/editor_group_tabs.h index e2ed6055aa..a0021e4833 100644 --- a/gtk2_ardour/editor_group_tabs.h +++ b/gtk2_ardour/editor_group_tabs.h @@ -37,7 +37,7 @@ private: } void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *); PBD::PropertyList default_properties () const; - std::string order_key () const; + ARDOUR::RouteSortOrderKey order_key () const; ARDOUR::RouteList selected_routes () const; void sync_order_keys (); }; diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 46a69ce6af..d891db6651 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -5411,8 +5411,7 @@ Editor::split_region () struct EditorOrderRouteSorter { bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) { - /* use of ">" forces the correct sort order */ - return a->order_key ("editor") < b->order_key ("editor"); + return a->order_key (EditorSort) < b->order_key (EditorSort); } }; diff --git a/gtk2_ardour/editor_routes.cc b/gtk2_ardour/editor_routes.cc index c4443cbed0..3faeba183f 100644 --- a/gtk2_ardour/editor_routes.cc +++ b/gtk2_ardour/editor_routes.cc @@ -520,7 +520,14 @@ EditorRoutes::redisplay () /* this reorder is caused by user action, so reassign sort order keys to tracks. */ - route->set_order_key (N_ ("editor"), order_key); + + if (route->is_master()) { + route->set_order_key (EditorSort, Route::MasterBusRemoteControlID); + } else if (route->is_monitor()) { + route->set_order_key (EditorSort, Route::MonitorBusRemoteControlID); + } else { + route->set_order_key (EditorSort, order_key++); + } } bool visible = tv->marked_for_display (); @@ -534,7 +541,6 @@ EditorRoutes::redisplay () } n++; - order_key++; } /* whenever we go idle, update the track view list to reflect the new order. @@ -557,7 +563,7 @@ EditorRoutes::redisplay () } if (!_redisplay_does_not_reset_order_keys && !_redisplay_does_not_sync_order_keys) { - _session->sync_order_keys (N_ ("editor")); + _session->sync_order_keys (EditorSort); } } @@ -569,7 +575,6 @@ EditorRoutes::route_deleted (Gtk::TreeModel::Path const &) } /* this could require an order reset & sync */ - _session->set_remote_control_ids(); _ignore_reorder = true; redisplay (); _ignore_reorder = false; @@ -591,7 +596,6 @@ EditorRoutes::visible_changed (std::string const & path) if (tv->set_marked_for_display (!visible)) { _redisplay_does_not_reset_order_keys = true; - _session->set_remote_control_ids(); update_visibility (); redisplay (); _redisplay_does_not_reset_order_keys = false; @@ -649,15 +653,6 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes) row[_columns.solo_safe_state] = (*x)->route()->solo_safe(); row[_columns.name_editable] = true; - _ignore_reorder = true; - - /* added a new fresh one at the end */ - if ((*x)->route()->order_key (N_ ("editor")) == -1) { - (*x)->route()->set_order_key (N_ ("editor"), _model->children().size()-1); - } - - _ignore_reorder = false; - boost::weak_ptr<Route> wr ((*x)->route()); (*x)->route()->gui_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::handle_gui_changes, this, _1, _2), gui_context()); @@ -833,13 +828,13 @@ EditorRoutes::reordered (TreeModel::Path const &, TreeModel::iterator const &, i * route list so that the visual arrangement of routes matches the order keys from the routes. */ void -EditorRoutes::sync_order_keys (string const & src) +EditorRoutes::sync_order_keys (RouteSortOrderKey src) { map<int, int> new_order; TreeModel::Children rows = _model->children(); TreeModel::Children::iterator ri; - if (src == N_ ("editor") || !_session || (_session->state_of_the_state() & (Session::Loading|Session::Deletion)) || rows.empty()) { + if (src == EditorSort || !_session || (_session->state_of_the_state() & (Session::Loading|Session::Deletion)) || rows.empty()) { return; } @@ -850,7 +845,7 @@ EditorRoutes::sync_order_keys (string const & src) boost::shared_ptr<Route> route = (*ri)[_columns.route]; int const old_key = order; - int const new_key = route->order_key (N_ ("editor")); + int const new_key = route->order_key (EditorSort); new_order[new_key] = old_key; @@ -1193,7 +1188,7 @@ EditorRoutes::selection_filter (Glib::RefPtr<TreeModel> const &, TreeModel::Path struct EditorOrderRouteSorter { bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) { /* use of ">" forces the correct sort order */ - return a->order_key (N_ ("editor")) < b->order_key (N_ ("editor")); + return a->order_key (EditorSort) < b->order_key (EditorSort); } }; @@ -1247,7 +1242,6 @@ void EditorRoutes::track_list_reorder (Gtk::TreeModel::Path const &, Gtk::TreeModel::iterator const &, int* /*new_order*/) { _redisplay_does_not_sync_order_keys = true; - _session->set_remote_control_ids(); redisplay (); _redisplay_does_not_sync_order_keys = false; } @@ -1370,7 +1364,7 @@ EditorRoutes::move_selected_tracks (bool up) } for (leading = view_routes.begin(); leading != view_routes.end(); ++leading) { - neworder.push_back (leading->second->order_key (N_ ("editor"))); + neworder.push_back (leading->second->order_key (EditorSort)); } #ifndef NDEBUG @@ -1381,7 +1375,7 @@ EditorRoutes::move_selected_tracks (bool up) _model->reorder (neworder); - _session->sync_order_keys (N_ ("editor")); + _session->sync_order_keys (EditorSort); } void diff --git a/gtk2_ardour/editor_routes.h b/gtk2_ardour/editor_routes.h index 5fad890faf..00631d914a 100644 --- a/gtk2_ardour/editor_routes.h +++ b/gtk2_ardour/editor_routes.h @@ -55,7 +55,7 @@ public: std::list<TimeAxisView*> views () const; void hide_all_tracks (bool); void clear (); - void sync_order_keys (std::string const &); + void sync_order_keys (ARDOUR::RouteSortOrderKey); private: diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc index eb9ea5c721..7b08eaeaa6 100644 --- a/gtk2_ardour/editor_selection.cc +++ b/gtk2_ardour/editor_selection.cc @@ -779,7 +779,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op) RouteTimeAxisView* closest = 0; int distance = INT_MAX; - int key = rtv->route()->order_key ("editor"); + int key = rtv->route()->order_key (EditorSort); for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) { @@ -794,7 +794,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op) if (result.second) { /* newly added to already_in_selection */ - int d = artv->route()->order_key ("editor"); + int d = artv->route()->order_key (EditorSort); d -= key; @@ -810,7 +810,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op) /* now add all tracks between that one and this one */ - int okey = closest->route()->order_key ("editor"); + int okey = closest->route()->order_key (EditorSort); if (okey > key) { swap (okey, key); @@ -820,7 +820,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op) RouteTimeAxisView* artv = dynamic_cast<RouteTimeAxisView*>(*x); if (artv && artv != rtv) { - int k = artv->route()->order_key ("editor"); + int k = artv->route()->order_key (EditorSort); if (k >= okey && k <= key) { diff --git a/gtk2_ardour/group_tabs.cc b/gtk2_ardour/group_tabs.cc index 9ce3b15046..d53b905846 100644 --- a/gtk2_ardour/group_tabs.cc +++ b/gtk2_ardour/group_tabs.cc @@ -435,24 +435,23 @@ GroupTabs::subgroup (RouteGroup* g, bool aux, Placement placement) } struct CollectSorter { - CollectSorter (string const & key) : _key (key) {} + CollectSorter (RouteSortOrderKey key) : _key (key) {} bool operator () (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) { return a->order_key (_key) < b->order_key (_key); } - string _key; + RouteSortOrderKey _key; }; struct OrderSorter { - OrderSorter (string const & key) : _key (key) {} + OrderSorter (RouteSortOrderKey key) : _key (key) {} bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) { - /* use of ">" forces the correct sort order */ return a->order_key (_key) < b->order_key (_key); } - string _key; + RouteSortOrderKey _key; }; /** Collect all members of a RouteGroup so that they are together in the Editor or Mixer. diff --git a/gtk2_ardour/group_tabs.h b/gtk2_ardour/group_tabs.h index d8c488c70f..fa6a7bac53 100644 --- a/gtk2_ardour/group_tabs.h +++ b/gtk2_ardour/group_tabs.h @@ -92,7 +92,7 @@ private: virtual void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *) {} virtual PBD::PropertyList default_properties () const = 0; - virtual std::string order_key () const = 0; + virtual ARDOUR::RouteSortOrderKey order_key () const = 0; virtual ARDOUR::RouteList selected_routes () const = 0; virtual void sync_order_keys () = 0; diff --git a/gtk2_ardour/mixer_group_tabs.cc b/gtk2_ardour/mixer_group_tabs.cc index db586eed7e..60a625c96d 100644 --- a/gtk2_ardour/mixer_group_tabs.cc +++ b/gtk2_ardour/mixer_group_tabs.cc @@ -170,10 +170,10 @@ MixerGroupTabs::default_properties () const return plist; } -string +RouteSortOrderKey MixerGroupTabs::order_key () const { - return X_("signal"); + return MixerSort; } RouteList @@ -192,5 +192,5 @@ MixerGroupTabs::selected_routes () const void MixerGroupTabs::sync_order_keys () { - _mixer->sync_order_keys (""); + _mixer->sync_order_keys (UndefinedSort); } diff --git a/gtk2_ardour/mixer_group_tabs.h b/gtk2_ardour/mixer_group_tabs.h index d8dd062280..0999dd9808 100644 --- a/gtk2_ardour/mixer_group_tabs.h +++ b/gtk2_ardour/mixer_group_tabs.h @@ -36,7 +36,7 @@ private: } PBD::PropertyList default_properties () const; - std::string order_key () const; + ARDOUR::RouteSortOrderKey order_key () const; ARDOUR::RouteList selected_routes () const; void sync_order_keys (); diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index 8dd83ad771..a29717211e 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -307,13 +307,11 @@ Mixer_UI::hide_window (GdkEventAny *ev) void Mixer_UI::add_strip (RouteList& routes) { - ENSURE_GUI_THREAD (*this, &Mixer_UI::add_strip, routes) - MixerStrip* strip; no_track_list_redisplay = true; strip_redisplay_does_not_sync_order_keys = true; - + for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) { boost::shared_ptr<Route> route = (*x); @@ -360,10 +358,6 @@ Mixer_UI::add_strip (RouteList& routes) row[track_columns.route] = route; row[track_columns.strip] = strip; - if (route->order_key (N_("signal")) == -1) { - route->set_order_key (N_("signal"), track_model->children().size()-1); - } - route->PropertyChanged.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::strip_property_changed, this, _1, strip), gui_context()); strip->WidthChanged.connect (sigc::mem_fun(*this, &Mixer_UI::strip_width_changed)); @@ -406,12 +400,12 @@ Mixer_UI::remove_strip (MixerStrip* strip) } void -Mixer_UI::sync_order_keys (string const & src) +Mixer_UI::sync_order_keys (RouteSortOrderKey src) { TreeModel::Children rows = track_model->children(); TreeModel::Children::iterator ri; - if (src == N_("signal") || !_session || (_session->state_of_the_state() & (Session::Loading|Session::Deletion)) || rows.empty()) { + if (src == MixerSort || !_session || (_session->state_of_the_state() & (Session::Loading|Session::Deletion)) || rows.empty()) { return; } @@ -423,7 +417,7 @@ Mixer_UI::sync_order_keys (string const & src) for (ri = rows.begin(); ri != rows.end(); ++ri, ++order) { boost::shared_ptr<Route> route = (*ri)[track_columns.route]; unsigned int old_key = order; - unsigned int new_key = route->order_key (N_("signal")); + unsigned int new_key = route->order_key (MixerSort); keys[new_key] = old_key; @@ -802,7 +796,6 @@ void Mixer_UI::track_list_reorder (const TreeModel::Path&, const TreeModel::iterator&, int* /*new_order*/) { strip_redisplay_does_not_sync_order_keys = true; - _session->set_remote_control_ids(); redisplay_track_list (); strip_redisplay_does_not_sync_order_keys = false; } @@ -812,7 +805,6 @@ Mixer_UI::track_list_change (const Gtk::TreeModel::Path&, const Gtk::TreeModel:: { // never reset order keys because of a property change strip_redisplay_does_not_reset_order_keys = true; - _session->set_remote_control_ids(); redisplay_track_list (); strip_redisplay_does_not_reset_order_keys = false; } @@ -822,7 +814,6 @@ Mixer_UI::track_list_delete (const Gtk::TreeModel::Path&) { /* this could require an order sync */ if (_session && !_session->deletion_in_progress()) { - _session->set_remote_control_ids(); redisplay_track_list (); } } @@ -832,13 +823,15 @@ Mixer_UI::redisplay_track_list () { TreeModel::Children rows = track_model->children(); TreeModel::Children::iterator i; - long order; - + long regular_order = 0; + long hidden_order = 999999; // arbitary high number + if (no_track_list_redisplay) { return; } - for (order = 0, i = rows.begin(); i != rows.end(); ++i, ++order) { + for (i = rows.begin(); i != rows.end(); ++i) { + MixerStrip* strip = (*i)[track_columns.strip]; if (strip == 0) { @@ -846,10 +839,6 @@ Mixer_UI::redisplay_track_list () continue; } - if (!strip_redisplay_does_not_reset_order_keys) { - strip->route()->set_order_key (N_("signal"), order); - } - bool const visible = (*i)[track_columns.visible]; if (visible) { @@ -859,16 +848,41 @@ Mixer_UI::redisplay_track_list () if (strip->route()->is_master() || strip->route()->is_monitor()) { out_packer.reorder_child (*strip, -1); + + if (!strip_redisplay_does_not_reset_order_keys) { + if (strip->route()->is_master()) { + strip->route()->set_order_key (MixerSort, Route::MasterBusRemoteControlID); + } else { + strip->route()->set_order_key (MixerSort, Route::MonitorBusRemoteControlID); + } + } + } else { strip_packer.reorder_child (*strip, -1); /* put at end */ + + if (!strip_redisplay_does_not_reset_order_keys) { + strip->route()->set_order_key (MixerSort, regular_order++); + } + } } else { if (strip->route()->is_master() || strip->route()->is_monitor()) { out_packer.pack_start (*strip, false, false); + if (!strip_redisplay_does_not_reset_order_keys) { + if (strip->route()->is_master()) { + strip->route()->set_order_key (MixerSort, Route::MasterBusRemoteControlID); + } else { + strip->route()->set_order_key (MixerSort, Route::MonitorBusRemoteControlID); + } + } } else { strip_packer.pack_start (*strip, false, false); + + if (!strip_redisplay_does_not_reset_order_keys) { + strip->route()->set_order_key (MixerSort, regular_order++); + } } strip->set_packed (true); } @@ -884,12 +898,16 @@ Mixer_UI::redisplay_track_list () strip_packer.remove (*strip); strip->set_packed (false); } + + if (!strip_redisplay_does_not_reset_order_keys) { + strip->route()->set_order_key (MixerSort, hidden_order++); + } } } } if (!strip_redisplay_does_not_reset_order_keys && !strip_redisplay_does_not_sync_order_keys) { - _session->sync_order_keys (N_("signal")); + _session->sync_order_keys (MixerSort); } _group_tabs->set_dirty (); @@ -924,8 +942,7 @@ Mixer_UI::strip_width_changed () struct SignalOrderRouteSorter { bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) { - /* use of ">" forces the correct sort order */ - return a->order_key (N_("signal")) < b->order_key (N_("signal")); + return a->order_key (MixerSort) < b->order_key (MixerSort); } }; diff --git a/gtk2_ardour/mixer_ui.h b/gtk2_ardour/mixer_ui.h index 08d7b6e487..f3d7845461 100644 --- a/gtk2_ardour/mixer_ui.h +++ b/gtk2_ardour/mixer_ui.h @@ -37,6 +37,7 @@ #include "pbd/signals.h" #include "ardour/ardour.h" +#include "ardour/types.h" #include "ardour/session_handle.h" #include "enums.h" @@ -244,7 +245,7 @@ class Mixer_UI : public Gtk::Window, public PBD::ScopedConnectionList, public AR Width _strip_width; - void sync_order_keys (std::string const &); + void sync_order_keys (ARDOUR::RouteSortOrderKey); bool strip_redisplay_does_not_reset_order_keys; bool strip_redisplay_does_not_sync_order_keys; bool ignore_sync; diff --git a/gtk2_ardour/port_group.cc b/gtk2_ardour/port_group.cc index 36b9ea1187..f313b2973f 100644 --- a/gtk2_ardour/port_group.cc +++ b/gtk2_ardour/port_group.cc @@ -312,7 +312,7 @@ struct RouteIOs { class RouteIOsComparator { public: bool operator() (RouteIOs const & a, RouteIOs const & b) { - return a.route->order_key (X_("editor")) < b.route->order_key (X_("editor")); + return a.route->order_key (EditorSort) < b.route->order_key (EditorSort); } }; diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index 0da6bde4f0..b6c81717a2 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -1716,27 +1716,39 @@ void RouteUI::open_remote_control_id_dialog () { ArdourDialog dialog (_("Remote Control ID")); + SpinButton* spin = 0; - uint32_t const limit = _session->ntracks() + _session->nbusses () + 4; + dialog.get_vbox()->set_border_width (18); - HBox* hbox = manage (new HBox); - hbox->set_spacing (6); - hbox->pack_start (*manage (new Label (_("Remote control ID:")))); - SpinButton* spin = manage (new SpinButton); - spin->set_digits (0); - spin->set_increments (1, 10); - spin->set_range (0, limit); - spin->set_value (_route->remote_control_id()); - hbox->pack_start (*spin); - dialog.get_vbox()->pack_start (*hbox); - - dialog.add_button (Stock::CANCEL, RESPONSE_CANCEL); - dialog.add_button (Stock::APPLY, RESPONSE_ACCEPT); + if (Config->get_remote_model() == UserOrdered) { + uint32_t const limit = _session->ntracks() + _session->nbusses () + 4; + + HBox* hbox = manage (new HBox); + hbox->set_spacing (6); + hbox->pack_start (*manage (new Label (_("Remote control ID:")))); + spin = manage (new SpinButton); + spin->set_digits (0); + spin->set_increments (1, 10); + spin->set_range (0, limit); + spin->set_value (_route->remote_control_id()); + hbox->pack_start (*spin); + dialog.get_vbox()->pack_start (*hbox); + + dialog.add_button (Stock::CANCEL, RESPONSE_CANCEL); + dialog.add_button (Stock::APPLY, RESPONSE_ACCEPT); + } else { + Label* l = manage (new Label()); + l->set_markup (string_compose (_("Remote Control IDs are currently determined by track/bus ordering in %1\n\n\n" + "<span size=\"small\" style=\"italic\">Use the User Interaction tab of the Preferences window if you want to change this</span>"), + (Config->get_remote_model() == MixerOrdered ? _("the mixer") : ("the editor")))); + dialog.get_vbox()->pack_start (*l); + dialog.add_button (Stock::OK, RESPONSE_CANCEL); + } dialog.show_all (); int const r = dialog.run (); - if (r == RESPONSE_ACCEPT) { + if (r == RESPONSE_ACCEPT && spin) { _route->set_remote_control_id (spin->get_value_as_int ()); } } diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index d1248d8b03..a15937377e 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -101,8 +101,8 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember, bool set_name (const std::string& str); static void set_name_in_state (XMLNode &, const std::string &); - int32_t order_key (std::string const &) const; - void set_order_key (std::string const &, int32_t); + int32_t order_key (RouteSortOrderKey) const; + void set_order_key (RouteSortOrderKey, int32_t); bool is_hidden() const { return _flags & Hidden; } bool is_master() const { return _flags & MasterOut; } @@ -420,19 +420,19 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember, MonitorBusRemoteControlID = 319, }; - void set_remote_control_id (uint32_t id, bool notify_class_listeners = true); + void set_remote_control_id (uint32_t id, bool notify_class_listeners = true); uint32_t remote_control_id () const; /* for things concerned about *this* route's RID */ PBD::Signal0<void> RemoteControlIDChanged; - /* for things concerned about any route's RID changes */ + /* for things concerned about *any* route's RID changes */ static PBD::Signal0<void> RemoteControlIDChange; - void sync_order_keys (std::string const &); - static PBD::Signal1<void,std::string const &> SyncOrderKeys; + void sync_order_keys (RouteSortOrderKey); + static PBD::Signal1<void,RouteSortOrderKey> SyncOrderKeys; bool has_external_redirects() const; @@ -518,7 +518,6 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember, void silence_unlocked (framecnt_t); ChanCount processor_max_streams; - uint32_t _remote_control_id; uint32_t pans_required() const; ChanCount n_process_buffers (); @@ -534,8 +533,9 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember, static uint32_t order_key_cnt; - typedef std::map<std::string, long> OrderKeys; - OrderKeys order_keys; + typedef std::map<RouteSortOrderKey,int32_t> OrderKeys; + OrderKeys order_keys; + uint32_t* _remote_control_id; void input_change_handler (IOChange, void *src); void output_change_handler (IOChange, void *src); diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 7f73d3ae77..eb84c0685e 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -235,7 +235,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi bool operator() (boost::shared_ptr<Route>, boost::shared_ptr<Route> b); }; - void sync_order_keys (std::string const &); + void sync_order_keys (RouteSortOrderKey); template<class T> void foreach_route (T *obj, void (T::*func)(Route&)); template<class T> void foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>)); @@ -464,8 +464,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void resort_routes (); void resort_routes_using (boost::shared_ptr<RouteList>); - void set_remote_control_ids(); - AudioEngine & engine() { return _engine; } AudioEngine const & engine () const { return _engine; } @@ -1488,7 +1486,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi XMLNode& get_control_protocol_state (); void set_history_depth (uint32_t depth); - void sync_order_keys (); static bool _disable_all_loaded_plugins; diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index 6d05bdbbd8..713e35ebab 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -351,6 +351,12 @@ namespace ARDOUR { PostFader }; + enum RouteSortOrderKey { + UndefinedSort, + EditorSort, + MixerSort + }; + enum MonitorModel { HardwareMonitoring, ///< JACK does monitoring SoftwareMonitoring, ///< Ardour does monitoring diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc index afe92ed5f7..1ef9047f57 100644 --- a/libs/ardour/enums.cc +++ b/libs/ardour/enums.cc @@ -89,6 +89,7 @@ setup_enum_writer () AutoState _AutoState; AutoStyle _AutoStyle; AutoConnectOption _AutoConnectOption; + RouteSortOrderKey _RouteSortOrderKey; Session::StateOfTheState _Session_StateOfTheState; Route::Flag _Route_Flag; Source::Flag _Source_Flag; @@ -397,6 +398,10 @@ setup_enum_writer () REGISTER_CLASS_ENUM (Route, MonitorOut); REGISTER_BITS (_Route_Flag); + REGISTER_ENUM (MixerSort); + REGISTER_ENUM (EditorSort); + REGISTER_BITS (_RouteSortOrderKey); + REGISTER_CLASS_ENUM (Source, Writable); REGISTER_CLASS_ENUM (Source, CanRename); REGISTER_CLASS_ENUM (Source, Broadcast); diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 83b1efce76..af30a112db 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -67,7 +67,7 @@ using namespace ARDOUR; using namespace PBD; uint32_t Route::order_key_cnt = 0; -PBD::Signal1<void,string const&> Route::SyncOrderKeys; +PBD::Signal1<void,RouteSortOrderKey> Route::SyncOrderKeys; PBD::Signal0<void> Route::RemoteControlIDChange; Route::Route (Session& sess, string name, Flag flg, DataType default_type) @@ -99,14 +99,6 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type) , _last_custom_meter_was_at_end (false) { processor_max_streams.reset(); - order_keys[N_("signal")] = order_key_cnt++; - - if (is_master()) { - set_remote_control_id (MasterBusRemoteControlID); - } else if (is_monitor()) { - set_remote_control_id (MonitorBusRemoteControlID); - } - } int @@ -203,11 +195,22 @@ Route::~Route () } _processors.clear (); + + delete _remote_control_id; } void Route::set_remote_control_id (uint32_t id, bool notify_class_listeners) { + if (Config->get_remote_model() != UserOrdered) { + return; + } + + if (id < 1) { + error << _("Remote Control ID's start at one, not zero") << endmsg; + return; + } + /* force IDs for master/monitor busses and prevent any other route from accidentally getting these IDs (i.e. legacy sessions) @@ -228,8 +231,11 @@ Route::set_remote_control_id (uint32_t id, bool notify_class_listeners) id += MonitorBusRemoteControlID; } - if (id != _remote_control_id) { - _remote_control_id = id; + if (id != remote_control_id()) { + if (!_remote_control_id) { + _remote_control_id = new uint32_t; + } + *_remote_control_id = id; RemoteControlIDChanged (); if (notify_class_listeners) { RemoteControlIDChange (); @@ -240,13 +246,27 @@ Route::set_remote_control_id (uint32_t id, bool notify_class_listeners) uint32_t Route::remote_control_id() const { - return _remote_control_id; + switch (Config->get_remote_model()) { + case MixerOrdered: + return order_key (MixerSort) + 1; + case EditorOrdered: + return order_key (EditorSort) + 1; + case UserOrdered: + if (_remote_control_id) { + return *_remote_control_id; + } + } + + /* fall back to MixerSort as the default */ + + return order_key (MixerSort) + 1; } int32_t -Route::order_key (std::string const & name) const +Route::order_key (RouteSortOrderKey key) const { - OrderKeys::const_iterator i = order_keys.find (name); + OrderKeys::const_iterator i = order_keys.find (key); + if (i == order_keys.end()) { return -1; } @@ -255,7 +275,7 @@ Route::order_key (std::string const & name) const } void -Route::set_order_key (std::string const & name, int32_t n) +Route::set_order_key (RouteSortOrderKey key, int32_t n) { bool changed = false; @@ -265,16 +285,24 @@ Route::set_order_key (std::string const & name, int32_t n) signal. */ - if (order_keys.find(name) == order_keys.end() || order_keys[name] != n) { - order_keys[name] = n; + if (order_keys.find (key) == order_keys.end() || order_keys[key] != n) { + order_keys[key] = n; changed = true; } if (Config->get_sync_all_route_ordering()) { for (OrderKeys::iterator x = order_keys.begin(); x != order_keys.end(); ++x) { - if (x->second != n) { - x->second = n; - changed = true; + + /* we do not sync the signal order keys for mixer + + * monitor because they are considered "external" to + * the ordering of other routes. + */ + + if ((!is_master() && !is_monitor()) || x->first != MixerSort) { + if (x->second != n) { + x->second = n; + changed = true; + } } } } @@ -290,7 +318,7 @@ Route::set_order_key (std::string const & name, int32_t n) * @param base Base key. */ void -Route::sync_order_keys (std::string const & base) +Route::sync_order_keys (RouteSortOrderKey base) { if (order_keys.empty()) { return; @@ -313,9 +341,17 @@ Route::sync_order_keys (std::string const & base) bool changed = false; for (; i != order_keys.end(); ++i) { - if (i->second != key) { - i->second = key; - changed = true; + + /* we do not sync the signal order keys for mixer + + * monitor because they are considered "external" to + * the ordering of other routes. + */ + + if ((!is_master() && !is_monitor()) || i->first != MixerSort) { + if (i->second != key) { + i->second = key; + changed = true; + } } } @@ -1421,12 +1457,7 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream boost::shared_ptr<IOProcessor> iop; if ((iop = boost::dynamic_pointer_cast<IOProcessor> (*i)) != 0) { - if (iop->input()) { - iop->input()->disconnect (this); - } - if (iop->output()) { - iop->output()->disconnect (this); - } + iop->disconnect (); } i = _processors.erase (i); @@ -1867,9 +1898,9 @@ Route::state(bool full_state) OrderKeys::iterator x = order_keys.begin(); while (x != order_keys.end()) { - order_string += string ((*x).first); + order_string += enum_2_string ((*x).first); order_string += '='; - snprintf (buf, sizeof(buf), "%ld", (*x).second); + snprintf (buf, sizeof(buf), "%" PRId32, (*x).second); order_string += buf; ++x; @@ -1895,10 +1926,12 @@ Route::state(bool full_state) node->add_child_nocopy (_mute_control->get_state ()); node->add_child_nocopy (_mute_master->get_state ()); - XMLNode* remote_control_node = new XMLNode (X_("RemoteControl")); - snprintf (buf, sizeof (buf), "%d", _remote_control_id); - remote_control_node->add_property (X_("id"), buf); - node->add_child_nocopy (*remote_control_node); + if (_remote_control_id) { + XMLNode* remote_control_node = new XMLNode (X_("RemoteControl")); + snprintf (buf, sizeof (buf), "%d", *_remote_control_id); + remote_control_node->add_property (X_("id"), buf); + node->add_child_nocopy (*remote_control_node); + } if (_comment.length()) { XMLNode *cmt = node->add_child ("Comment"); @@ -2089,7 +2122,18 @@ Route::set_state (const XMLNode& node, int version) error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining) << endmsg; } else { - set_order_key (remaining.substr (0, equal), n); + string keyname = remaining.substr (0, equal); + RouteSortOrderKey sk; + + if (keyname == "signal") { + sk = MixerSort; + } else if (keyname == "editor") { + sk = EditorSort; + } else { + RouteSortOrderKey sk = (RouteSortOrderKey) string_2_enum (remaining.substr (0, equal), sk); + } + + set_order_key (sk, n); } } @@ -2285,7 +2329,18 @@ Route::set_state_2X (const XMLNode& node, int version) error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining) << endmsg; } else { - set_order_key (remaining.substr (0, equal), n); + string keyname = remaining.substr (0, equal); + RouteSortOrderKey sk; + + if (keyname == "signal") { + sk = MixerSort; + } else if (keyname == "editor") { + sk = EditorSort; + } else { + RouteSortOrderKey sk = (RouteSortOrderKey) string_2_enum (remaining.substr (0, equal), sk); + } + + set_order_key (sk, n); } } diff --git a/libs/ardour/route_graph.cc b/libs/ardour/route_graph.cc index fbf406fd92..13264ff9fa 100644 --- a/libs/ardour/route_graph.cc +++ b/libs/ardour/route_graph.cc @@ -170,7 +170,7 @@ struct RouteRecEnabledComparator if (r1->record_enabled()) { if (r2->record_enabled()) { /* both rec-enabled, just use signal order */ - return r1->order_key(N_("signal")) < r2->order_key(N_("signal")); + return r1->order_key (MixerSort) < r2->order_key (MixerSort); } else { /* r1 rec-enabled, r2 not rec-enabled, run r2 early */ return false; @@ -181,7 +181,7 @@ struct RouteRecEnabledComparator return true; } else { /* neither rec-enabled, use signal order */ - return r1->order_key(N_("signal")) < r2->order_key(N_("signal")); + return r1->order_key (MixerSort) < r2->order_key (MixerSort); } } } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index f6d5b2bbd1..a38f6a129a 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -1515,7 +1515,7 @@ Session::resort_routes_using (boost::shared_ptr<RouteList> r) DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n"); for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n", - (*i)->name(), (*i)->order_key ("signal"))); + (*i)->name(), (*i)->order_key (MixerSort))); } #endif @@ -1602,12 +1602,9 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost: string port; RouteList new_routes; list<boost::shared_ptr<MidiTrack> > ret; - uint32_t control_id; cerr << "Adding MIDI track with in = " << input << " out = " << output << endl; - control_id = next_control_id (); - bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("MIDI"); while (how_many) { @@ -1650,7 +1647,10 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost: } track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this)); - track->set_remote_control_id (control_id); + + if (Config->get_remote_model() == UserOrdered) { + track->set_remote_control_id (next_control_id()); + } new_routes.push_back (track); ret.push_back (track); @@ -1839,9 +1839,6 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod string port; RouteList new_routes; list<boost::shared_ptr<AudioTrack> > ret; - uint32_t control_id; - - control_id = next_control_id (); bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Audio"); @@ -1892,8 +1889,9 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod track->non_realtime_input_change(); track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this)); - track->set_remote_control_id (control_id); - ++control_id; + if (Config->get_remote_model() == UserOrdered) { + track->set_remote_control_id (next_control_id()); + } new_routes.push_back (track); ret.push_back (track); @@ -1921,33 +1919,6 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod return ret; } -void -Session::set_remote_control_ids () -{ - RemoteModel m = Config->get_remote_model(); - bool emit_signal = false; - - boost::shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (MixerOrdered == m) { - int32_t order = (*i)->order_key(N_("signal")); - (*i)->set_remote_control_id (order+1, false); - emit_signal = true; - } else if (EditorOrdered == m) { - int32_t order = (*i)->order_key(N_("editor")); - (*i)->set_remote_control_id (order+1, false); - emit_signal = true; - } else if (UserOrdered == m) { - //do nothing ... only changes to remote id's are initiated by user - } - } - - if (emit_signal) { - Route::RemoteControlIDChange(); - } -} - /** Caller must not hold process lock. * @param name_template string to use for the start of the name, or "" to use "Bus". */ @@ -1958,9 +1929,6 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r uint32_t bus_id = 0; string port; RouteList ret; - uint32_t control_id; - - control_id = next_control_id (); bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus"); @@ -2002,8 +1970,9 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r if (route_group) { route_group->add (bus); } - bus->set_remote_control_id (control_id); - ++control_id; + if (Config->get_remote_model() == UserOrdered) { + bus->set_remote_control_id (next_control_id()); + } bus->add_internal_return (); @@ -2390,7 +2359,7 @@ Session::remove_route (boost::shared_ptr<Route> route) route->drop_references (); - sync_order_keys (N_("session")); + sync_order_keys (UndefinedSort); Route::RemoteControlIDChange(); /* EMIT SIGNAL */ @@ -3481,7 +3450,7 @@ Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost:: if (b->is_monitor()) { return false; } - return a->order_key(N_("signal")) < b->order_key(N_("signal")); + return a->order_key (MixerSort) < b->order_key (MixerSort); } bool @@ -4182,7 +4151,7 @@ Session::add_automation_list(AutomationList *al) } void -Session::sync_order_keys (std::string const & base) +Session::sync_order_keys (RouteSortOrderKey base) { if (deletion_in_progress()) { return; @@ -4200,10 +4169,6 @@ Session::sync_order_keys (std::string const & base) } Route::SyncOrderKeys (base); // EMIT SIGNAL - - /* this might not do anything */ - - set_remote_control_ids (); } /** @return true if there is at least one record-enabled track, otherwise false */ @@ -4781,7 +4746,32 @@ Session::session_name_is_legal (const string& path) uint32_t Session::next_control_id () const { - return ntracks() + nbusses() + 1; + int subtract = 0; + + /* the master and monitor bus remote ID's occupy a different + * "namespace" than regular routes. their existence doesn't + * affect normal (low) numbered routes. + */ + + if (_master_out) { + subtract++; + } + + if (_monitor_out) { + subtract++; + } + + /* remote control IDs are based either on this + value, or signal order, which is zero-based. so we have + to ensure consistency of zero-based-ness for both + sources of the number. + + we actually add 1 to the value to form an actual + remote control ID, which is 1-based. + */ + + cerr << "Next control ID will be " << ntracks() + (nbusses() - subtract) << endl; + return ntracks() + (nbusses() - subtract); } bool diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 9ea202ee67..1509a757eb 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -3109,11 +3109,13 @@ Session::controllable_by_descriptor (const ControllableDescriptor& desc) } case ControllableDescriptor::RemoteControlID: + cerr << "RID " << desc.rid() << endl; r = route_by_remote_id (desc.rid()); break; } if (!r) { + cerr << "no controllable with no route\n"; return c; } @@ -3196,11 +3198,15 @@ Session::controllable_by_descriptor (const ControllableDescriptor& desc) --send; } + cerr << "Look for send " << send << endl; + boost::shared_ptr<Processor> p = r->nth_send (send); if (p) { boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p); boost::shared_ptr<Amp> a = s->amp(); + + cerr << " looked for send " << send << " got " << s << " amp = " << a << endl; if (a) { c = s->amp()->gain_control(); @@ -3551,14 +3557,12 @@ Session::config_changed (std::string p, bool ours) } else { switch_to_sync_source (config.get_sync_source()); } - } else if (p == "remote-model") { - set_remote_control_ids (); } else if (p == "denormal-model") { setup_fpu (); } else if (p == "history-depth") { set_history_depth (Config->get_history_depth()); } else if (p == "sync-all-route-ordering") { - sync_order_keys ("session"); + sync_order_keys (UndefinedSort); } else if (p == "initial-program-change") { if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) { |