13
0

drastic rethink of the relationship between remote control ID and route order keys. unless the user explicitly switches to UserOrdered, Route::_remote_control_id is an unallocated pointer, and Route::remote_control_id() simply returns a value based on the relevant order_key() value. Also, change the key used in the Route::order_keys std::map<> from a string to an enum, since there is no evidence that we are benefitting from the theoretical benefit of using a string. Generally tidy up allocation of order keys so that the master and monitor busses always get a "special" MixerSort key value, based on the MMC ID for master (already defined within Ardour), and all other tracks/busses start at zero. Syncing keys between editor and mixer will leave the MixerSort key for the master and monitor bus alone, reflecting the fact that we display these in their own distinct parts of the GUI and they are not orderable like other tracks or busses within the mixer window

git-svn-id: svn://localhost/ardour2/branches/3.0@12923 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2012-06-25 12:46:13 +00:00
parent f2f35e50a0
commit 97d920593f
23 changed files with 268 additions and 189 deletions

View File

@ -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);
}
};

View File

@ -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);
}

View File

@ -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 ();
};

View File

@ -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);
}
};

View File

@ -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

View File

@ -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:

View File

@ -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) {

View File

@ -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.

View File

@ -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;

View File

@ -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);
}

View File

@ -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 ();

View File

@ -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);
}
};

View File

@ -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;

View File

@ -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);
}
};

View File

@ -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 ());
}
}

View File

@ -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);

View File

@ -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;

View File

@ -351,6 +351,12 @@ namespace ARDOUR {
PostFader
};
enum RouteSortOrderKey {
UndefinedSort,
EditorSort,
MixerSort
};
enum MonitorModel {
HardwareMonitoring, ///< JACK does monitoring
SoftwareMonitoring, ///< Ardour does monitoring

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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) {