13
0

first vaguely working version using PresentationInfo

remote control ID and "order keys" have been removed.
This commit is contained in:
Paul Davis 2016-05-16 07:30:28 -04:00
parent bae9474e9f
commit e0ff70cf86
65 changed files with 1193 additions and 1076 deletions

View File

@ -1818,7 +1818,8 @@ ARDOUR_UI::session_add_mixed_track (
const string& name_template,
bool strict_io,
PluginInfoPtr instrument,
Plugin::PresetRecord* pset)
Plugin::PresetRecord* pset,
ARDOUR::PresentationInfo::order_t order)
{
list<boost::shared_ptr<MidiTrack> > tracks;
@ -1828,7 +1829,7 @@ ARDOUR_UI::session_add_mixed_track (
}
try {
tracks = _session->new_midi_track (input, output, instrument, ARDOUR::Normal, route_group, how_many, name_template, pset);
tracks = _session->new_midi_track (input, output, instrument, pset, route_group, how_many, name_template, order, ARDOUR::Normal);
if (tracks.size() != how_many) {
error << string_compose(P_("could not create %1 new mixed track", "could not create %1 new mixed tracks", how_many), how_many) << endmsg;
@ -1854,7 +1855,8 @@ ARDOUR_UI::session_add_midi_bus (
const string& name_template,
bool strict_io,
PluginInfoPtr instrument,
Plugin::PresetRecord* pset)
Plugin::PresetRecord* pset,
ARDOUR::PresentationInfo::order_t order)
{
RouteList routes;
@ -1864,7 +1866,8 @@ ARDOUR_UI::session_add_midi_bus (
}
try {
routes = _session->new_midi_route (route_group, how_many, name_template, instrument, pset);
routes = _session->new_midi_route (route_group, how_many, name_template, instrument, pset, PresentationInfo::MidiBus, order);
if (routes.size() != how_many) {
error << string_compose(P_("could not create %1 new Midi Bus", "could not create %1 new Midi Busses", how_many), how_many) << endmsg;
}
@ -1890,15 +1893,16 @@ ARDOUR_UI::session_add_midi_route (
const string& name_template,
bool strict_io,
PluginInfoPtr instrument,
Plugin::PresetRecord* pset)
Plugin::PresetRecord* pset,
ARDOUR::PresentationInfo::order_t order)
{
ChanCount one_midi_channel;
one_midi_channel.set (DataType::MIDI, 1);
if (disk) {
session_add_mixed_track (one_midi_channel, one_midi_channel, route_group, how_many, name_template, strict_io, instrument, pset);
session_add_mixed_track (one_midi_channel, one_midi_channel, route_group, how_many, name_template, strict_io, order, instrument, pset);
} else {
session_add_midi_bus (route_group, how_many, name_template, strict_io, instrument, pset);
session_add_midi_bus (route_group, how_many, name_template, strict_io, order, instrument, pset);
}
}
@ -1911,8 +1915,8 @@ ARDOUR_UI::session_add_audio_route (
RouteGroup* route_group,
uint32_t how_many,
string const & name_template,
bool strict_io
)
bool strict_io,
ARDOUR::PresentationInfo::order_t order)
{
list<boost::shared_ptr<AudioTrack> > tracks;
RouteList routes;
@ -1924,7 +1928,7 @@ ARDOUR_UI::session_add_audio_route (
try {
if (track) {
tracks = _session->new_audio_track (input_channels, output_channels, mode, route_group, how_many, name_template);
tracks = _session->new_audio_track (input_channels, output_channels, route_group, how_many, name_template, order, mode);
if (tracks.size() != how_many) {
error << string_compose (P_("could not create %1 new audio track", "could not create %1 new audio tracks", how_many), how_many)
@ -1933,7 +1937,7 @@ ARDOUR_UI::session_add_audio_route (
} else {
routes = _session->new_audio_route (input_channels, output_channels, route_group, how_many, name_template);
routes = _session->new_audio_route (input_channels, output_channels, route_group, how_many, name_template, PresentationInfo::AudioBus, order);
if (routes.size() != how_many) {
error << string_compose (P_("could not create %1 new audio bus", "could not create %1 new audio busses", how_many), how_many)
@ -2377,7 +2381,7 @@ ARDOUR_UI::transport_forward (int option)
}
void
ARDOUR_UI::toggle_record_enable (uint32_t rid)
ARDOUR_UI::toggle_record_enable (uint16_t rid)
{
if (!_session) {
return;
@ -2385,7 +2389,7 @@ ARDOUR_UI::toggle_record_enable (uint32_t rid)
boost::shared_ptr<Route> r;
if ((r = _session->route_by_remote_id (rid)) != 0) {
if ((r = _session->get_remote_nth_route (rid)) != 0) {
boost::shared_ptr<Track> t;
@ -3902,15 +3906,15 @@ ARDOUR_UI::cleanup_peakfiles ()
}
}
void
ARDOUR_UI::setup_order_hint (AddRouteDialog::InsertAt place)
PresentationInfo::order_t
ARDOUR_UI::translate_order (AddRouteDialog::InsertAt place)
{
uint32_t order_hint = UINT32_MAX;
if (editor->get_selection().tracks.empty()) {
return;
return PresentationInfo::max_order;
}
PresentationInfo::order_t order_hint = PresentationInfo::max_order;
/*
we want the new routes to have their order keys set starting from
the highest order key in the selection + 1 (if available).
@ -3919,42 +3923,21 @@ ARDOUR_UI::setup_order_hint (AddRouteDialog::InsertAt place)
if (place == AddRouteDialog::AfterSelection) {
RouteTimeAxisView *rtav = dynamic_cast<RouteTimeAxisView*> (editor->get_selection().tracks.back());
if (rtav) {
order_hint = rtav->route()->order_key();
order_hint = rtav->route()->presentation_info().group_order();
order_hint++;
}
} else if (place == AddRouteDialog::BeforeSelection) {
RouteTimeAxisView *rtav = dynamic_cast<RouteTimeAxisView*> (editor->get_selection().tracks.front());
if (rtav) {
order_hint = rtav->route()->order_key();
order_hint = rtav->route()->presentation_info().group_order();
}
} else if (place == AddRouteDialog::First) {
order_hint = 0;
} else {
/* leave order_hint at UINT32_MAX */
/* leave order_hint at max_order */
}
if (order_hint == UINT32_MAX) {
/** AddRouteDialog::Last or selection with first/last not a RouteTimeAxisView
* not setting an order hint will place new routes last.
*/
return;
}
_session->set_order_hint (order_hint);
/* create a gap in the existing route order keys to accomodate new routes.*/
boost::shared_ptr <RouteList> rd = _session->get_routes();
for (RouteList::iterator ri = rd->begin(); ri != rd->end(); ++ri) {
boost::shared_ptr<Route> rt (*ri);
if (rt->is_monitor()) {
continue;
}
if (rt->order_key () >= order_hint) {
rt->set_order_key (rt->order_key () + add_route_dialog->count());
}
}
return order_hint;
}
void
@ -4001,7 +3984,7 @@ ARDOUR_UI::add_route ()
return;
}
setup_order_hint(add_route_dialog->insert_at());
PresentationInfo::order_t order = translate_order (add_route_dialog->insert_at());
string template_path = add_route_dialog->track_template();
DisplaySuspender ds;
@ -4033,19 +4016,19 @@ ARDOUR_UI::add_route ()
switch (add_route_dialog->type_wanted()) {
case AddRouteDialog::AudioTrack:
session_add_audio_track (input_chan.n_audio(), output_chan.n_audio(), add_route_dialog->mode(), route_group, count, name_template, strict_io);
session_add_audio_track (input_chan.n_audio(), output_chan.n_audio(), add_route_dialog->mode(), route_group, count, name_template, strict_io, order);
break;
case AddRouteDialog::MidiTrack:
session_add_midi_track (route_group, count, name_template, strict_io, instrument);
session_add_midi_track (route_group, count, name_template, strict_io, instrument, 0, order);
break;
case AddRouteDialog::MixedTrack:
session_add_mixed_track (input_chan, output_chan, route_group, count, name_template, strict_io, instrument, 0);
session_add_mixed_track (input_chan, output_chan, route_group, count, name_template, strict_io, instrument, 0, order);
break;
case AddRouteDialog::AudioBus:
session_add_audio_bus (input_chan.n_audio(), output_chan.n_audio(), route_group, count, name_template, strict_io);
session_add_audio_bus (input_chan.n_audio(), output_chan.n_audio(), route_group, count, name_template, strict_io, order);
break;
case AddRouteDialog::MidiBus:
session_add_midi_bus (route_group, count, name_template, strict_io, instrument, 0);
session_add_midi_bus (route_group, count, name_template, strict_io, instrument, 0, order);
break;
case AddRouteDialog::VCAMaster:
session_add_vca (name_template, count);

View File

@ -281,9 +281,10 @@ public:
ARDOUR::RouteGroup* route_group,
uint32_t how_many,
std::string const & name_template,
bool strict_io
bool strict_io,
ARDOUR::PresentationInfo::order_t order
) {
session_add_audio_route (true, input_channels, output_channels, mode, route_group, how_many, name_template, strict_io);
session_add_audio_route (true, input_channels, output_channels, mode, route_group, how_many, name_template, strict_io, order);
}
void session_add_audio_bus (
@ -292,9 +293,10 @@ public:
ARDOUR::RouteGroup* route_group,
uint32_t how_many,
std::string const & name_template,
bool strict_io
bool strict_io,
ARDOUR::PresentationInfo::order_t order
) {
session_add_audio_route (false, input_channels, output_channels, ARDOUR::Normal, route_group, how_many, name_template, strict_io);
session_add_audio_route (false, input_channels, output_channels, ARDOUR::Normal, route_group, how_many, name_template, strict_io, order);
}
void session_add_midi_track (
@ -302,15 +304,20 @@ public:
uint32_t how_many,
std::string const & name_template,
bool strict_io,
ARDOUR::PresentationInfo::order_t order,
ARDOUR::PluginInfoPtr instrument,
ARDOUR::Plugin::PresetRecord* preset = NULL) {
session_add_midi_route (true, route_group, how_many, name_template, strict_io, instrument, preset);
session_add_midi_route (true, route_group, how_many, name_template, strict_io, order, instrument, preset);
}
void session_add_mixed_track (const ARDOUR::ChanCount&, const ARDOUR::ChanCount&, ARDOUR::RouteGroup*, uint32_t, std::string const &, bool, ARDOUR::PluginInfoPtr, ARDOUR::Plugin::PresetRecord*);
void session_add_midi_bus (ARDOUR::RouteGroup*, uint32_t, std::string const &, bool, ARDOUR::PluginInfoPtr, ARDOUR::Plugin::PresetRecord*);
void session_add_audio_route (bool, int32_t, int32_t, ARDOUR::TrackMode, ARDOUR::RouteGroup *, uint32_t, std::string const &, bool);
void session_add_midi_route (bool, ARDOUR::RouteGroup *, uint32_t, std::string const &, bool, ARDOUR::PluginInfoPtr, ARDOUR::Plugin::PresetRecord*);
void session_add_mixed_track (const ARDOUR::ChanCount&, const ARDOUR::ChanCount&, ARDOUR::RouteGroup*, uint32_t, std::string const &, bool, ARDOUR::PluginInfoPtr,
ARDOUR::PresentationInfo::order_t order);
void session_add_midi_bus (ARDOUR::RouteGroup*, uint32_t, std::string const &, bool, ARDOUR::PluginInfoPtr,
ARDOUR::PresentationInfo::order_t order);
void session_add_audio_route (bool, int32_t, int32_t, ARDOUR::TrackMode, ARDOUR::RouteGroup *, uint32_t, std::string const &, bool,
ARDOUR::PresentationInfo::order_t order);
void session_add_midi_route (bool, ARDOUR::RouteGroup *, uint32_t, std::string const &, bool, ARDOUR::PresentationInfo::order_t order,
ARDOUR::PluginInfoPtr, ARDOUR::Plugin::PresetRecord*);
void display_insufficient_ports_message ();
@ -401,7 +408,7 @@ private:
void button_change_tabbable_visibility (Gtkmm2ext::Tabbable*);
void key_change_tabbable_visibility (Gtkmm2ext::Tabbable*);
void toggle_editor_and_mixer ();
void tabbable_state_change (Gtkmm2ext::Tabbable&);
void toggle_meterbridge ();
@ -664,7 +671,7 @@ private:
bool save_as_progress_update (float fraction, int64_t cnt, int64_t total, Gtk::Label* label, Gtk::ProgressBar* bar);
void save_session_as ();
void rename_session ();
void setup_order_hint (AddRouteDialog::InsertAt);
ARDOUR::PresentationInfo::order_t translate_order (AddRouteDialog::InsertAt);
int create_mixer ();
int create_editor ();
@ -720,7 +727,7 @@ private:
void install_actions ();
void toggle_record_enable (uint32_t);
void toggle_record_enable (uint16_t);
uint32_t rec_enabled_streams;
void count_recenabled_streams (ARDOUR::Route&);

View File

@ -1000,7 +1000,7 @@ Editor::control_unselect ()
}
void
Editor::control_select (uint32_t rid, Selection::Operation op)
Editor::control_select (uint16_t rid, Selection::Operation op)
{
/* handles the (static) signal from the ControlProtocol class that
* requests setting the selected track to a given RID
@ -1010,7 +1010,7 @@ Editor::control_select (uint32_t rid, Selection::Operation op)
return;
}
boost::shared_ptr<Route> r = _session->route_by_remote_id (rid);
boost::shared_ptr<Route> r = _session->get_remote_nth_route (rid);
if (!r) {
return;

View File

@ -1088,7 +1088,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void control_step_tracks_down ();
void control_view (uint32_t);
void control_scroll (float);
void control_select (uint32_t rid, Selection::Operation);
void control_select (uint16_t rid, Selection::Operation);
void control_unselect ();
void access_action (std::string,std::string);
bool deferred_control_scroll (framepos_t);

View File

@ -937,7 +937,7 @@ Editor::finish_bringing_in_material (boost::shared_ptr<Region> region,
{
if (!existing_track) {
if (ar) {
list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (in_chans, out_chans, Normal, 0, 1));
list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (in_chans, out_chans, 0, 1, string(), PresentationInfo::max_order, Normal));
if (at.empty()) {
return -1;
@ -954,7 +954,8 @@ Editor::finish_bringing_in_material (boost::shared_ptr<Region> region,
_session->new_midi_track (ChanCount (DataType::MIDI, 1),
ChanCount (DataType::MIDI, 1),
instrument,
Normal, 0, 1));
0, 1, string(),
PresentationInfo::max_order));
if (mt.empty()) {
return -1;
@ -990,7 +991,7 @@ Editor::finish_bringing_in_material (boost::shared_ptr<Region> region,
return -1;
}
list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (in_chans, out_chans, Destructive));
list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (in_chans, out_chans, 0, 1, string(), PresentationInfo::max_order, Destructive));
if (!at.empty()) {
boost::shared_ptr<Playlist> playlist = at.front()->playlist();
boost::shared_ptr<Region> copy (RegionFactory::create (region, true));

View File

@ -1280,12 +1280,12 @@ Editor::drop_regions (const Glib::RefPtr<Gdk::DragContext>& /*context*/,
output_chan = session()->master_out()->n_inputs().n_audio();
}
list<boost::shared_ptr<AudioTrack> > audio_tracks;
audio_tracks = session()->new_audio_track (region->n_channels(), output_chan, ARDOUR::Normal, 0, 1, region->name());
audio_tracks = session()->new_audio_track (region->n_channels(), output_chan, 0, 1, region->name(), PresentationInfo::max_order, ARDOUR::Normal);
rtav = axis_view_from_route (audio_tracks.front());
} else if (boost::dynamic_pointer_cast<MidiRegion> (region)) {
ChanCount one_midi_port (DataType::MIDI, 1);
list<boost::shared_ptr<MidiTrack> > midi_tracks;
midi_tracks = session()->new_midi_track (one_midi_port, one_midi_port, boost::shared_ptr<ARDOUR::PluginInfo>(), ARDOUR::Normal, 0, 1, region->name());
midi_tracks = session()->new_midi_track (one_midi_port, one_midi_port, boost::shared_ptr<ARDOUR::PluginInfo>(), 0, 1, region->name(), PresentationInfo::max_order, ARDOUR::Normal);
rtav = axis_view_from_route (midi_tracks.front());
} else {
return;

View File

@ -525,12 +525,12 @@ Drag::add_midi_region (MidiTimeAxisView* view, bool commit)
return boost::shared_ptr<Region>();
}
struct EditorOrderTimeAxisViewSorter {
struct PresentationInfoTimeAxisViewSorter {
bool operator() (TimeAxisView* a, TimeAxisView* b) {
RouteTimeAxisView* ra = dynamic_cast<RouteTimeAxisView*> (a);
RouteTimeAxisView* rb = dynamic_cast<RouteTimeAxisView*> (b);
assert (ra && rb);
return ra->route()->order_key () < rb->route()->order_key ();
return ra->route()->presentation_info () < rb->route()->presentation_info();
}
};
@ -546,7 +546,7 @@ RegionDrag::RegionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<Re
*/
TrackViewList track_views = _editor->track_views;
track_views.sort (EditorOrderTimeAxisViewSorter ());
track_views.sort (PresentationInfoTimeAxisViewSorter ());
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
_time_axis_views.push_back (*i);
@ -1397,7 +1397,7 @@ RegionMoveDrag::create_destination_time_axis (boost::shared_ptr<Region> region,
if ((Config->get_output_auto_connect() & AutoConnectMaster) && _editor->session()->master_out()) {
output_chan = _editor->session()->master_out()->n_inputs().n_audio();
}
audio_tracks = _editor->session()->new_audio_track (region->n_channels(), output_chan, ARDOUR::Normal, 0, 1, region->name());
audio_tracks = _editor->session()->new_audio_track (region->n_channels(), output_chan, 0, 1, region->name(), PresentationInfo::max_order, ARDOUR::Normal);
RouteTimeAxisView* rtav = _editor->axis_view_from_route (audio_tracks.front());
if (rtav) {
rtav->set_height (original->current_height());
@ -1406,7 +1406,7 @@ RegionMoveDrag::create_destination_time_axis (boost::shared_ptr<Region> region,
} else {
ChanCount one_midi_port (DataType::MIDI, 1);
list<boost::shared_ptr<MidiTrack> > midi_tracks;
midi_tracks = _editor->session()->new_midi_track (one_midi_port, one_midi_port, boost::shared_ptr<ARDOUR::PluginInfo>(), ARDOUR::Normal, 0, 1, region->name());
midi_tracks = _editor->session()->new_midi_track (one_midi_port, one_midi_port, boost::shared_ptr<ARDOUR::PluginInfo>(), 0, 1, region->name(), PresentationInfo::max_order, ARDOUR::Normal);
RouteTimeAxisView* rtav = _editor->axis_view_from_route (midi_tracks.front());
if (rtav) {
rtav->set_height (original->current_height());

View File

@ -192,8 +192,3 @@ EditorGroupTabs::selected_routes () const
return rl;
}
void
EditorGroupTabs::sync_order_keys ()
{
_editor->_routes->sync_order_keys_from_treeview ();
}

View File

@ -37,5 +37,4 @@ private:
}
void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *);
ARDOUR::RouteList selected_routes () const;
void sync_order_keys ();
};

View File

@ -6153,12 +6153,6 @@ Editor::split_region ()
}
}
struct EditorOrderRouteSorter {
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
return a->order_key () < b->order_key ();
}
};
void
Editor::select_next_route()
{

View File

@ -244,7 +244,7 @@ Editor::do_ptimport (std::string ptpath,
} else {
// Put on a new track
DEBUG_TRACE (DEBUG::FileUtils, string_compose ("\twav(%1) reg(%2) new_tr(%3)\n", a->reg.wave.filename.c_str(), a->reg.index, nth));
list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (1, 2, Normal, 0, 1));
list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (1, 2, 0, 1, string(), PresentationInfo::max_order, Normal));
if (at.empty()) {
return;
}

View File

@ -28,6 +28,7 @@
#include "pbd/unwind.h"
#include "ardour/debug.h"
#include "ardour/audio_track.h"
#include "ardour/midi_track.h"
#include "ardour/route.h"
#include "ardour/session.h"
@ -313,9 +314,8 @@ EditorRoutes::EditorRoutes (Editor* e)
_display.set_enable_search (false);
Route::SyncOrderKeys.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::sync_treeview_from_order_keys, this), gui_context());
Route::PluginSetup.connect_same_thread (*this, boost::bind (&EditorRoutes::plugin_setup, this, _1, _2, _3));
Stripable::PresentationInfoChange.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::sync_treeview_from_presentation_info, this), gui_context());
}
bool
@ -623,27 +623,28 @@ EditorRoutes::row_deleted (Gtk::TreeModel::Path const &)
* when a route is actually removed. we don't differentiate between
* the two cases.
*
* note that the sync_orders_keys() step may not actually change any
* RID's (e.g. the last track may be removed, so all other tracks keep
* the same RID), which means that no redisplay would happen. so we
* have to force a redisplay.
* note that the sync_presentation_info_from_treeview() step may not
* actually change any presentation info (e.g. the last track may be
* removed, so all other tracks keep the same presentation info), which
* means that no redisplay would happen. so we have to force a
* redisplay.
*/
DEBUG_TRACE (DEBUG::OrderKeys, "editor routes treeview row deleted\n");
DisplaySuspender ds;
sync_order_keys_from_treeview ();
sync_presentation_info_from_treeview ();
}
void
EditorRoutes::reordered (TreeModel::Path const &, TreeModel::iterator const &, int* /*what*/)
{
/* reordering implies that RID's will change, so sync_order_keys() will
cause a redisplay.
/* reordering implies that RID's will change, so
sync_presentation_info_from_treeview() will cause a redisplay.
*/
DEBUG_TRACE (DEBUG::OrderKeys, "editor routes treeview reordered\n");
sync_order_keys_from_treeview ();
sync_presentation_info_from_treeview ();
}
void
@ -691,7 +692,7 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
for (Gtk::TreeModel::Children::iterator it = _model->children().begin(); it != _model->children().end(); ++it) {
boost::shared_ptr<Route> r = (*it)[_columns.route];
if (r->order_key() == (routes.front()->route()->order_key() + routes.size())) {
if (r->presentation_info().group_order() == (routes.front()->route()->presentation_info().group_order() + routes.size())) {
insert_iter = it;
break;
}
@ -767,7 +768,7 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
/* now update route order keys from the treeview/track display order */
if (!from_scratch) {
sync_order_keys_from_treeview ();
sync_presentation_info_from_treeview ();
}
}
@ -862,7 +863,7 @@ EditorRoutes::update_visibility ()
/* force route order keys catch up with visibility changes
*/
sync_order_keys_from_treeview ();
sync_presentation_info_from_treeview ();
}
void
@ -905,60 +906,10 @@ EditorRoutes::reset_remote_control_ids ()
return;
}
TreeModel::Children rows = _model->children();
if (rows.empty()) {
return;
}
DEBUG_TRACE (DEBUG::OrderKeys, "editor reset remote control ids\n");
TreeModel::Children::iterator ri;
bool rid_change = false;
uint32_t rid = 1;
uint32_t invisible_key = UINT32_MAX;
for (ri = rows.begin(); ri != rows.end(); ++ri) {
/* skip two special values */
if (rid == Route::MasterBusRemoteControlID) {
rid++;
}
if (rid == Route::MonitorBusRemoteControlID) {
rid++;
}
boost::shared_ptr<Route> route = (*ri)[_columns.route];
bool visible = (*ri)[_columns.visible];
if (!route->is_master() && !route->is_monitor()) {
uint32_t new_rid = (visible ? rid : invisible_key--);
if (new_rid != route->remote_control_id()) {
route->set_remote_control_id_explicit (new_rid);
rid_change = true;
}
if (visible) {
rid++;
}
}
}
if (rid_change) {
/* tell the world that we changed the remote control IDs */
_session->notify_remote_id_change ();
}
sync_presentation_info_from_treeview ();
}
void
EditorRoutes::sync_order_keys_from_treeview ()
EditorRoutes::sync_presentation_info_from_treeview ()
{
if (_ignore_reorder || !_session || _session->deletion_in_progress()) {
return;
@ -970,60 +921,46 @@ EditorRoutes::sync_order_keys_from_treeview ()
return;
}
DEBUG_TRACE (DEBUG::OrderKeys, "editor sync order keys from treeview\n");
TreeModel::Children::iterator ri;
bool changed = false;
bool rid_change = false;
uint32_t order = 0;
uint32_t rid = 1;
uint32_t invisible_key = UINT32_MAX;
bool change = false;
PresentationInfo::order_t order = 0;
/* hmm, problem ... editor doesn't represent all Stripables... we can't
reset the whole presentation order from here.
*/
for (ri = rows.begin(); ri != rows.end(); ++ri) {
boost::shared_ptr<Route> route = (*ri)[_columns.route];
bool visible = (*ri)[_columns.visible];
uint32_t old_key = route->order_key ();
if (order != old_key) {
route->set_order_key (order);
changed = true;
if (route->presentation_info().special ()) {
continue;
}
if ((Config->get_remote_model() == MixerOrdered) && !route->is_master() && !route->is_monitor()) {
uint32_t new_rid = (visible ? rid : invisible_key--);
if (new_rid != route->remote_control_id()) {
route->set_remote_control_id_explicit (new_rid);
rid_change = true;
}
if (visible) {
rid++;
}
if (!visible) {
route->presentation_info().set_flag (PresentationInfo::Hidden);
} else {
route->presentation_info().unset_flag (PresentationInfo::Hidden);
}
if (order != route->presentation_info().group_order()) {
route->set_presentation_group_order_explicit (order);
change = true;
}
++order;
}
if (changed) {
/* tell the world that we changed the editor sort keys */
_session->sync_order_keys ();
}
if (rid_change) {
/* tell the world that we changed the remote control IDs */
_session->notify_remote_id_change ();
if (change) {
Stripable::PresentationInfoChange(); /* EMIT SIGNAL */
}
}
void
EditorRoutes::sync_treeview_from_order_keys ()
EditorRoutes::sync_treeview_from_presentation_info ()
{
/* Some route order key(s) have been changed, make sure that
we update out tree/list model and GUI to reflect the change.
@ -1033,7 +970,7 @@ EditorRoutes::sync_treeview_from_order_keys ()
return;
}
DEBUG_TRACE (DEBUG::OrderKeys, "editor sync model from order keys.\n");
DEBUG_TRACE (DEBUG::OrderKeys, "editor sync model from presentation info.\n");
/* we could get here after either a change in the Mixer or Editor sort
* order, but either way, the mixer order keys reflect the intended
@ -1053,7 +990,11 @@ EditorRoutes::sync_treeview_from_order_keys ()
for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++old_order) {
boost::shared_ptr<Route> route = (*ri)[_columns.route];
sorted.push_back (OrderKeys (old_order, route->order_key ()));
sorted.push_back (OrderKeys (old_order, route->presentation_info().group_order()));
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("build new order: route %3 old = %1 new = %1\n",
old_order,
route->presentation_info().group_order(),
route->name()));
}
SortByNewDisplayOrder cmp;
@ -1128,7 +1069,7 @@ EditorRoutes::set_all_tracks_visibility (bool yn)
/* force route order keys catch up with visibility changes
*/
sync_order_keys_from_treeview ();
sync_presentation_info_from_treeview ();
}
void
@ -1193,7 +1134,7 @@ EditorRoutes::set_all_audio_midi_visibility (int tracks, bool yn)
/* force route order keys catch up with visibility changes
*/
sync_order_keys_from_treeview ();
sync_presentation_info_from_treeview ();
}
void
@ -1427,7 +1368,7 @@ EditorRoutes::selection_filter (Glib::RefPtr<TreeModel> const &, TreeModel::Path
return true;
}
struct EditorOrderRouteSorter
struct PresentationInfoRouteSorter
{
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
if (a->is_master()) {
@ -1437,7 +1378,7 @@ struct EditorOrderRouteSorter
/* everything else before master */
return false;
}
return a->order_key () < b->order_key ();
return a->presentation_info().global_order () < b->presentation_info().global_order ();
}
};
@ -1453,7 +1394,7 @@ EditorRoutes::initial_display ()
RouteList r (*_session->get_routes());
r.sort (EditorOrderRouteSorter ());
r.sort (PresentationInfoRouteSorter ());
_editor->add_routes (r);
}
@ -1575,7 +1516,7 @@ EditorRoutes::move_selected_tracks (bool up)
}
for (leading = view_routes.begin(); leading != view_routes.end(); ++leading) {
uint32_t order = leading->second->order_key ();
uint32_t order = (uint32_t) leading->second->presentation_info().group_order ();
neworder.push_back (order);
}
@ -1781,7 +1722,7 @@ EditorRoutes::show_tracks_with_regions_at_playhead ()
/* force route order keys catch up with visibility changes
*/
sync_order_keys_from_treeview ();
sync_presentation_info_from_treeview ();
}
int

View File

@ -61,7 +61,7 @@ public:
std::list<TimeAxisView*> views () const;
void hide_all_tracks (bool);
void clear ();
void sync_order_keys_from_treeview ();
void sync_presentation_info_from_treeview ();
void reset_remote_control_ids ();
private:
@ -76,7 +76,7 @@ private:
void on_tv_solo_safe_toggled (std::string const &);
void build_menu ();
void show_menu ();
void sync_treeview_from_order_keys ();
void sync_treeview_from_presentation_info ();
void row_deleted (Gtk::TreeModel::Path const &);
void visible_changed (std::string const &);
void active_changed (std::string const &);

View File

@ -791,7 +791,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 ();
int key = rtv->route()->presentation_info().global_order ();
for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
@ -806,7 +806,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 ();
int d = artv->route()->presentation_info().global_order ();
d -= key;
@ -822,7 +822,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 ();
int okey = closest->route()->presentation_info().global_order ();
if (okey > key) {
swap (okey, key);
@ -832,7 +832,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 ();
int k = artv->route()->presentation_info().global_order ();
if (k >= okey && k <= key) {

View File

@ -107,7 +107,7 @@ EditorSummary::set_session (Session* s)
if (_session) {
Region::RegionPropertyChanged.connect (region_property_connection, invalidator (*this), boost::bind (&EditorSummary::set_background_dirty, this), gui_context());
Route::RemoteControlIDChange.connect (route_ctrl_id_connection, invalidator (*this), boost::bind (&EditorSummary::set_background_dirty, this), gui_context());
Stripable::PresentationInfoChange.connect (route_ctrl_id_connection, invalidator (*this), boost::bind (&EditorSummary::set_background_dirty, this), gui_context());
_editor->playhead_cursor->PositionChanged.connect (position_connection, invalidator (*this), boost::bind (&EditorSummary::playhead_position_changed, this, _1), gui_context());
_session->StartTimeChanged.connect (_session_connections, invalidator (*this), boost::bind (&EditorSummary::set_background_dirty, this), gui_context());
_session->EndTimeChanged.connect (_session_connections, invalidator (*this), boost::bind (&EditorSummary::set_background_dirty, this), gui_context());

View File

@ -18,8 +18,6 @@
*/
#include "export_channel_selector.h"
#include <algorithm>
#include "pbd/convert.h"
@ -33,6 +31,9 @@
#include <sstream>
#include "export_channel_selector.h"
#include "route_sorter.h"
#include "i18n.h"
using namespace std;
@ -40,12 +41,6 @@ using namespace Glib;
using namespace ARDOUR;
using namespace PBD;
struct EditorOrderRouteSorter {
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
return a->order_key () < b->order_key ();
}
};
PortExportChannelSelector::PortExportChannelSelector (ARDOUR::Session * session, ProfileManagerPtr manager) :
ExportChannelSelector (session, manager),
channels_label (_("Channels:"), Gtk::ALIGN_LEFT),
@ -126,7 +121,7 @@ PortExportChannelSelector::fill_route_list ()
channel_view.add_route (master);
}
routes.sort (EditorOrderRouteSorter ());
routes.sort (PresentationInfoSorter ());
for (RouteList::iterator it = routes.begin(); it != routes.end(); ++it) {
if ((*it)->is_master () || (*it)->is_monitor ()) {
@ -700,7 +695,7 @@ TrackExportChannelSelector::add_track (boost::shared_ptr<Route> route)
row[track_cols.selected] = false;
row[track_cols.label] = route->name();
row[track_cols.route] = route;
row[track_cols.order_key] = route->order_key();
row[track_cols.order_key] = route->presentation_info().global_order();
}
void

View File

@ -451,13 +451,13 @@ GroupTabs::un_subgroup (RouteGroup* g)
struct CollectSorter {
bool operator () (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
return a->order_key () < b->order_key ();
return a->presentation_info () < b->presentation_info();
}
};
struct OrderSorter {
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
return a->order_key () < b->order_key ();
return a->presentation_info() < b->presentation_info();
}
};
@ -480,7 +480,7 @@ GroupTabs::collect (RouteGroup* g)
int coll = -1;
while (i != group_routes->end() && j != routes->end()) {
int const k = (*j)->order_key ();
PresentationInfo::order_t const k = (*j)->presentation_info ().group_order();
if (*i == *j) {
@ -491,21 +491,21 @@ GroupTabs::collect (RouteGroup* g)
--diff;
}
(*j)->set_order_key (coll);
(*j)->set_presentation_group_order_explicit (coll);
++coll;
++i;
} else {
(*j)->set_order_key (k + diff);
(*j)->set_presentation_group_order_explicit (k + diff);
}
++j;
}
_session->sync_order_keys ();
_session->notify_presentation_info_change ();
}
void

View File

@ -92,7 +92,6 @@ private:
virtual void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *) {}
virtual ARDOUR::RouteList selected_routes () const = 0;
virtual void sync_order_keys () = 0;
void new_from_selection ();
void new_from_rec_enabled ();

View File

@ -61,7 +61,6 @@ SESSION(PositionChanged, PositionChanged, 1)
SESSION(Located, Located, 0)
SESSION(RoutesReconnected, session_routes_reconnected, 0)
SESSION(RouteAdded, RouteAdded, 1)
SESSION(RouteAddedOrRemoved, RouteAddedOrRemoved, 1)
SESSION(RouteGroupPropertyChanged, RouteGroupPropertyChanged, 1)
SESSION(RouteAddedToRouteGroup, RouteAddedToRouteGroup, 2)
SESSION(RouteRemovedFromRouteGroup, RouteRemovedFromRouteGroup, 2)
@ -70,9 +69,6 @@ SESSION(RouteGroupAdded, route_group_added, 1)
SESSION(RouteGroupRemoved, route_group_removed, 0)
SESSION(RouteGroupsReordered, route_groups_reordered, 0)
// route static globals
STATIC(SyncOrderKeys, &Route::SyncOrderKeys, 0)
// plugin manager instance
STATIC(PluginListChanged, &(PluginManager::instance().PluginListChanged), 0)
STATIC(PluginStatusesChanged, &(PluginManager::instance().PluginStatusesChanged), 0)

View File

@ -801,12 +801,12 @@ MeterStrip::name_changed () {
}
name_label.set_text(_route->name ());
if (_session && _session->config.get_track_name_number()) {
const int64_t track_number = _route->track_number ();
const uint64_t track_number = _route->track_number();
if (track_number == 0) {
number_label.set_text("-");
number_label.hide();
} else {
number_label.set_text (PBD::to_string (abs(_route->track_number ()), std::dec));
number_label.set_text (PBD::to_string (track_number, std::dec));
number_label.show();
}
const int tnh = 4 + std::max(2u, _session->track_number_decimals()) * 8; // TODO 8 = max_width_of_digit_0_to_9()

View File

@ -40,7 +40,6 @@
#include "ardour/audio_track.h"
#include "ardour/midi_track.h"
#include "ardour/route_sorters.h"
#include "meterbridge.h"
@ -124,7 +123,6 @@ Meterbridge::Meterbridge ()
signal_delete_event().connect (sigc::mem_fun (*this, &Meterbridge::hide_window));
signal_configure_event().connect (sigc::mem_fun (*ARDOUR_UI::instance(), &ARDOUR_UI::configure_handler));
Route::SyncOrderKeys.connect (*this, invalidator (*this), boost::bind (&Meterbridge::sync_order_keys, this), gui_context());
MeterStrip::CatchDeletion.connect (*this, invalidator (*this), boost::bind (&Meterbridge::remove_strip, this, _1), gui_context());
MeterStrip::MetricChanged.connect (*this, invalidator (*this), boost::bind(&Meterbridge::resync_order, this), gui_context());
MeterStrip::ConfigurationChanged.connect (*this, invalidator (*this), boost::bind(&Meterbridge::queue_resize, this), gui_context());
@ -400,6 +398,20 @@ Meterbridge::on_scroll()
metrics_right.set_metric_mode(mm_right, mt_right);
}
struct PresentationInfoRouteSorter
{
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
if (a->is_master()) {
/* master before everything else */
return true;
} else if (b->is_master()) {
/* everything else before b */
return false;
}
return a->presentation_info() < b->presentation_info();
}
};
void
Meterbridge::set_session (Session* s)
{
@ -422,7 +434,7 @@ Meterbridge::set_session (Session* s)
_show_master = _session->config.get_show_master_on_meterbridge();
_show_midi = _session->config.get_show_midi_on_meterbridge();
ARDOUR::SignalOrderRouteSorter sorter;
PresentationInfoRouteSorter sorter;
boost::shared_ptr<RouteList> routes = _session->get_routes();
RouteList copy(*routes);

View File

@ -107,7 +107,7 @@ class Meterbridge :
/* everything comes before b */
return true;
}
return a->order_key () < b->order_key ();
return a->presentation_info() < b->presentation_info ();
}
};

View File

@ -193,8 +193,3 @@ MixerGroupTabs::selected_routes () const
return rl;
}
void
MixerGroupTabs::sync_order_keys ()
{
_mixer->sync_order_keys_from_treeview ();
}

View File

@ -36,7 +36,6 @@ private:
}
ARDOUR::RouteList selected_routes () const;
void sync_order_keys ();
Mixer_UI* _mixer;
};

View File

@ -42,10 +42,10 @@
#include "ardour/amp.h"
#include "ardour/debug.h"
#include "ardour/audio_track.h"
#include "ardour/midi_track.h"
#include "ardour/plugin_manager.h"
#include "ardour/route_group.h"
#include "ardour/route_sorters.h"
#include "ardour/session.h"
#include "ardour/vca.h"
#include "ardour/vca_manager.h"
@ -107,7 +107,7 @@ Mixer_UI::Mixer_UI ()
, _maximised (false)
, _show_mixer_list (true)
{
Route::SyncOrderKeys.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::sync_treeview_from_order_keys, this), gui_context());
Stripable::PresentationInfoChange.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::sync_treeview_from_presentation_info, this), gui_context());
/* bindings was already set in MixerActor constructor */
@ -427,7 +427,7 @@ Mixer_UI::add_strips (RouteList& routes)
nroutes++;
if (r->order_key() == (routes.front()->order_key() + routes.size())) {
if (r->presentation_info().group_order() == (routes.front()->presentation_info().group_order() + routes.size())) {
insert_iter = it;
break;
}
@ -512,7 +512,7 @@ Mixer_UI::add_strips (RouteList& routes)
no_track_list_redisplay = false;
track_display.set_model (track_model);
sync_order_keys_from_treeview ();
sync_presentation_info_from_treeview ();
redisplay_track_list ();
}
@ -576,69 +576,9 @@ Mixer_UI::remove_strip (MixerStrip* strip)
}
void
Mixer_UI::reset_remote_control_ids ()
Mixer_UI::sync_presentation_info_from_treeview ()
{
if (Config->get_remote_model() == UserOrdered || !_session || _session->deletion_in_progress()) {
return;
}
TreeModel::Children rows = track_model->children();
if (rows.empty()) {
return;
}
DEBUG_TRACE (DEBUG::OrderKeys, "mixer resets remote control ids after remote model change\n");
TreeModel::Children::iterator ri;
bool rid_change = false;
uint32_t rid = 1;
uint32_t invisible_key = UINT32_MAX;
for (ri = rows.begin(); ri != rows.end(); ++ri) {
/* skip two special values */
if (rid == Route::MasterBusRemoteControlID) {
rid++;
}
if (rid == Route::MonitorBusRemoteControlID) {
rid++;
}
boost::shared_ptr<Route> route = (*ri)[track_columns.route];
bool visible = (*ri)[track_columns.visible];
if (!route) {
continue;
}
if (!route->is_master() && !route->is_monitor()) {
uint32_t new_rid = (visible ? rid : invisible_key--);
if (new_rid != route->remote_control_id()) {
route->set_remote_control_id_explicit (new_rid);
rid_change = true;
}
if (visible) {
rid++;
}
}
}
if (rid_change) {
/* tell the world that we changed the remote control IDs */
_session->notify_remote_id_change ();
}
}
void
Mixer_UI::sync_order_keys_from_treeview ()
{
if (ignore_reorder || !_session || _session->deletion_in_progress()) {
if (ignore_reorder || !_session || _session->deletion_in_progress() || (Config->get_remote_model() != MixerOrdered)) {
return;
}
@ -651,58 +591,46 @@ Mixer_UI::sync_order_keys_from_treeview ()
DEBUG_TRACE (DEBUG::OrderKeys, "mixer sync order keys from model\n");
TreeModel::Children::iterator ri;
bool changed = false;
bool rid_change = false;
bool change = false;
uint32_t order = 0;
uint32_t rid = 1;
uint32_t invisible_key = UINT32_MAX;
for (ri = rows.begin(); ri != rows.end(); ++ri) {
boost::shared_ptr<Route> route = (*ri)[track_columns.route];
bool visible = (*ri)[track_columns.visible];
if (!route) {
continue;
}
uint32_t old_key = route->order_key ();
if (order != old_key) {
route->set_order_key (order);
changed = true;
if (route->presentation_info().special()) {
continue;
}
if ((Config->get_remote_model() == MixerOrdered) && !route->is_master() && !route->is_monitor()) {
if (!visible) {
route->presentation_info().set_flag (PresentationInfo::Hidden);
} else {
route->presentation_info().unset_flag (PresentationInfo::Hidden);
}
uint32_t new_rid = (visible ? rid : invisible_key--);
if (new_rid != route->remote_control_id()) {
route->set_remote_control_id_explicit (new_rid);
rid_change = true;
}
if (visible) {
rid++;
}
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("route %1 old order %2 new order %3\n", route->name(), route->presentation_info().group_order(), order));
if (order != route->presentation_info().group_order()) {
route->set_presentation_group_order_explicit (order);
change = true;
}
++order;
}
if (changed) {
/* tell everyone that we changed the mixer sort keys */
_session->sync_order_keys ();
}
if (rid_change) {
/* tell the world that we changed the remote control IDs */
_session->notify_remote_id_change ();
if (change) {
DEBUG_TRACE (DEBUG::OrderKeys, "... notify PI change from mixer GUI\n");
_session->notify_presentation_info_change ();
}
}
void
Mixer_UI::sync_treeview_from_order_keys ()
Mixer_UI::sync_treeview_from_presentation_info ()
{
if (!_session || _session->deletion_in_progress()) {
return;
@ -736,7 +664,7 @@ Mixer_UI::sync_treeview_from_order_keys ()
for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri) {
boost::shared_ptr<Route> route = (*ri)[track_columns.route];
if (route) {
max_route_order_key = max (route->order_key(), max_route_order_key);
max_route_order_key = max (route->presentation_info().group_order(), max_route_order_key);
}
}
@ -749,7 +677,7 @@ Mixer_UI::sync_treeview_from_order_keys ()
*/
sorted.push_back (OrderKeys (old_order, max_route_order_key + ++vca_cnt));
} else {
sorted.push_back (OrderKeys (old_order, route->order_key ()));
sorted.push_back (OrderKeys (old_order, route->presentation_info().group_order()));
}
}
@ -1007,10 +935,10 @@ Mixer_UI::update_track_visibility ()
}
}
/* force route order keys catch up with visibility changes
/* force presentation catch up with visibility changes
*/
sync_order_keys_from_treeview ();
sync_presentation_info_from_treeview ();
}
redisplay_track_list ();
@ -1207,7 +1135,7 @@ void
Mixer_UI::track_list_reorder (const TreeModel::Path&, const TreeModel::iterator&, int* /*new_order*/)
{
DEBUG_TRACE (DEBUG::OrderKeys, "mixer UI treeview reordered\n");
sync_order_keys_from_treeview ();
sync_presentation_info_from_treeview ();
}
void
@ -1221,7 +1149,7 @@ Mixer_UI::track_list_delete (const Gtk::TreeModel::Path&)
*/
DEBUG_TRACE (DEBUG::OrderKeys, "mixer UI treeview row deleted\n");
sync_order_keys_from_treeview ();
sync_presentation_info_from_treeview ();
if (_route_deletion_in_progress) {
redisplay_track_list ();
@ -1302,8 +1230,10 @@ Mixer_UI::redisplay_track_list ()
if (n_masters == 0) {
UIConfiguration::instance().set_mixer_strip_visibility (VisibilityGroup::remove_element (UIConfiguration::instance().get_mixer_strip_visibility(), X_("VCA")));
vca_scroller.hide ();
} else {
UIConfiguration::instance().set_mixer_strip_visibility (VisibilityGroup::add_element (UIConfiguration::instance().get_mixer_strip_visibility(), X_("VCA")));
vca_scroller.show ();
}
_group_tabs->set_dirty ();
@ -1336,12 +1266,19 @@ Mixer_UI::strip_width_changed ()
}
struct PresentationInfoRouteSorter
{
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
return a->presentation_info().global_order () < b->presentation_info().global_order ();
}
};
void
Mixer_UI::initial_track_display ()
{
boost::shared_ptr<RouteList> routes = _session->get_routes();
RouteList copy (*routes);
ARDOUR::SignalOrderRouteSorter sorter;
PresentationInfoRouteSorter sorter;
copy.sort (sorter);
@ -1355,8 +1292,6 @@ Mixer_UI::initial_track_display ()
add_strips (copy);
}
_session->sync_order_keys ();
redisplay_track_list ();
}
@ -2133,8 +2068,6 @@ Mixer_UI::parameter_changed (string const & p)
for (list<MixerStrip*>::iterator i = strips.begin(); i != strips.end(); ++i) {
(*i)->set_width_enum (s ? Narrow : Wide, this);
}
} else if (p == "remote-model") {
reset_remote_control_ids ();
} else if (p == "use-monitor-bus") {
if (_session && !_session->monitor_out()) {
monitor_section_detached ();

View File

@ -320,10 +320,8 @@ class Mixer_UI : public Gtkmm2ext::Tabbable, public PBD::ScopedConnectionList, p
Width _strip_width;
void sync_order_keys_from_treeview ();
void sync_treeview_from_order_keys ();
void reset_remote_control_ids ();
void reset_order_keys ();
void sync_presentation_info_from_treeview ();
void sync_treeview_from_presentation_info ();
bool ignore_reorder;

View File

@ -316,7 +316,7 @@ struct RouteIOs {
class RouteIOsComparator {
public:
bool operator() (RouteIOs const & a, RouteIOs const & b) {
return a.route->order_key () < b.route->order_key ();
return a.route->presentation_info ().group_order() < b.route->presentation_info().group_order();
}
};

View File

@ -159,7 +159,7 @@ PortMatrix::init ()
_session->engine().PortRegisteredOrUnregistered.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports, this), gui_context());
/* watch for route order keys changing, which changes the order of things in our global ports list(s) */
Route::SyncOrderKeys.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports_proxy, this), gui_context());
Stripable::PresentationInfoChange.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports_proxy, this), gui_context());
/* Part 3: other stuff */

View File

@ -2031,7 +2031,7 @@ RouteUI::open_remote_control_id_dialog ()
spin->set_digits (0);
spin->set_increments (1, 10);
spin->set_range (0, limit);
spin->set_value (_route->remote_control_id());
spin->set_value (_route->presentation_info().group_order());
hbox->pack_start (*spin);
dialog.get_vbox()->pack_start (*hbox);
@ -2043,14 +2043,14 @@ RouteUI::open_remote_control_id_dialog ()
l->set_markup (string_compose (_("The remote control ID of %1 is: %2\n\n\n"
"The remote control ID of %3 cannot be changed."),
Gtkmm2ext::markup_escape_text (_route->name()),
_route->remote_control_id(),
_route->presentation_info().group_order(),
(_route->is_master() ? _("the master bus") : _("the monitor bus"))));
} else {
l->set_markup (string_compose (_("The remote control ID of %5 is: %2\n\n\n"
"Remote Control IDs are currently determined by track/bus ordering in %6.\n\n"
"%3Use the User Interaction tab of the Preferences window if you want to change this%4"),
(is_track() ? _("track") : _("bus")),
_route->remote_control_id(),
_route->presentation_info().group_order(),
"<span size=\"small\" style=\"italic\">",
"</span>",
Gtkmm2ext::markup_escape_text (_route->name()),
@ -2064,7 +2064,7 @@ RouteUI::open_remote_control_id_dialog ()
int const r = dialog.run ();
if (r == RESPONSE_ACCEPT && spin) {
_route->set_remote_control_id (spin->get_value_as_int ());
_route->set_presentation_group_order_explicit (spin->get_value_as_int ());
}
}

View File

@ -16,6 +16,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <gtkmm/stock.h>
#include "pbd/convert.h"
#include "ardour/rc_configuration.h"
@ -26,8 +28,9 @@
#include "gtkmm2ext/doi.h"
#include "gtkmm2ext/keyboard.h"
#include "gui_thread.h"
#include "ardour_dialog.h"
#include "floating_text_entry.h"
#include "gui_thread.h"
#include "tooltips.h"
#include "vca_master_strip.h"
@ -47,6 +50,7 @@ VCAMasterStrip::VCAMasterStrip (Session* s, boost::shared_ptr<VCA> v)
, _vca (v)
, gain_meter (s, 250)
, context_menu (0)
, delete_dialog (0)
{
gain_meter.set_controls (boost::shared_ptr<Route>(),
boost::shared_ptr<PeakMeter>(),
@ -150,6 +154,9 @@ VCAMasterStrip::VCAMasterStrip (Session* s, boost::shared_ptr<VCA> v)
VCAMasterStrip::~VCAMasterStrip ()
{
delete delete_dialog;
delete context_menu;
CatchDeletion (this); /* EMIT SIGNAL */
}
@ -193,10 +200,31 @@ VCAMasterStrip::name() const
void
VCAMasterStrip::hide_clicked ()
{
/* get everything to deassign. This will also delete ourselves (when
* idle) and that in turn will remove us from the Mixer GUI
*/
_session->vca_manager().remove_vca (_vca);
if (!delete_dialog) {
delete_dialog = new MessageDialog (_("Removing a Master will deassign all slaves. Remove it anyway?"),
true, MESSAGE_WARNING, BUTTONS_YES_NO, true);
delete_dialog->signal_response().connect (sigc::mem_fun (*this, &VCAMasterStrip::hide_confirmation));
}
delete_dialog->set_position (Gtk::WIN_POS_MOUSE);
delete_dialog->present ();
}
void
VCAMasterStrip::hide_confirmation (int response)
{
delete_dialog->hide ();
switch (response) {
case RESPONSE_OK:
/* get everything to deassign. This will also delete ourselves (when
* idle) and that in turn will remove us from the Mixer GUI
*/
_session->vca_manager().remove_vca (_vca);
break;
default:
break;
}
}
bool

View File

@ -68,6 +68,7 @@ class VCAMasterStrip : public AxisView, public Gtk::EventBox
ArdourButton assign_button;
Gtk::Menu* context_menu;
PBD::ScopedConnectionList vca_connections;
Gtk::MessageDialog* delete_dialog;
void hide_clicked();
bool width_button_pressed (GdkEventButton *);
@ -87,6 +88,7 @@ class VCAMasterStrip : public AxisView, public Gtk::EventBox
void vca_property_changed (PBD::PropertyChange const & what_changed);
void update_vca_name ();
void build_context_menu ();
void hide_confirmation (int);
void self_delete ();
};

View File

@ -34,7 +34,7 @@ class AudioFileSource;
class LIBARDOUR_API AudioTrack : public Track
{
public:
AudioTrack (Session&, std::string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal);
AudioTrack (Session&, std::string name, TrackMode m = Normal);
~AudioTrack ();
int set_mode (TrackMode m);

View File

@ -37,7 +37,7 @@ class Session;
class LIBARDOUR_API MidiTrack : public Track
{
public:
MidiTrack (Session&, std::string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal);
MidiTrack (Session&, std::string name, TrackMode m = Normal);
~MidiTrack ();
int init ();

View File

@ -25,6 +25,7 @@
#include "ardour/slavable_automation_control.h"
#include "ardour/mute_master.h"
#include "ardour/libardour_visibility.h"
namespace ARDOUR {

View File

@ -0,0 +1,303 @@
/*
Copyright (C) 2016 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __libardour_presentation_info_h__
#define __libardour_presentation_info_h__
#include <iostream>
#include <string>
#include <stdint.h>
#include "ardour/libardour_visibility.h"
class XMLNode;
namespace ARDOUR {
class LIBARDOUR_API PresentationInfo
{
public:
/* a PresentationInfo object exists to share information between
* different user interfaces (e.g. GUI and a Mackie Control surface)
* about:
*
* - ordering
* - selection status
* - visibility
* - object identity
*
* ORDERING
*
* One UI takes control of ordering by setting the "order" value for
* the PresentationInfo component of every Stripable object. In Ardour,
* this is done by the GUI (mostly because it is very hard for the user
* to re-order things on a control surface).
*
* Ordering is a complex beast, however. Different user interfaces may
* display things in different ways. For example, the GUI of Ardour
* allows the user to mix busses in between tracks. A control surface
* may do the same, but may also allow the user to press a button that
* makes it show only busses, or only MIDI tracks. At that point, the
* ordering on the surface differs from the ordering in the GUI.
*
* The ordering is given via a combination of an object type and a
* simple numeric position within that type. The object types at this
* time are:
*
* Route
* - object has inputs and outputs; processes data
* Output
* - Route used to connect to outside the application (MasterOut, MonitorOut)
* Special
* - special type of Route (e.g. Auditioner)
* VCA
* - no data flows through; control only
*
* Objects with a numeric order of zero are considered unsorted. This
* applies (for now) to special objects such as the master out,
* auditioner and monitor out. The rationale here is that the GUI
* presents these objects in special ways, rather than as part of some
* (potentially) re-orderable container. The same is true for hardware
* surfaces, where the master fader (for instance) is typically
* separate and distinct from anything else.
*
* There are several pathways for the order being set:
*
* - object created during session loading from XML
* - numeric order will be set during ::set_state(), based on
* - type will be set during ctor call
*
* - object created in response to user request
* - numeric order will be set by Session, before adding
* to container.
* - type set during ctor call
*
*
* OBJECT IDENTITY
*
* Control surfaces/protocols often need to be able to get a handle on
* an object identified only abstractly, such as the "5th audio track"
* or "the master out". A PresentationInfo object uniquely identifies
* all objects in this way through the combination of its _order member
* and part of its _flags member. The _flags member identifies the type
* of object, as well as selection/hidden status. The type may never
* change after construction (not strictly the constructor itself, but
* a more generalized notion of construction, as in "ready to use").
*
* SELECTION
*
* When an object is selected, its _flags member will have the Selected
* bit set.
*
* VISIBILITY
*
* When an object is hidden, its _flags member will have the Hidden
* bit set.
*
*
*/
enum Flag {
/* Type information */
AudioTrack = 0x1,
MidiTrack = 0x2,
AudioBus = 0x4,
MidiBus = 0x8,
VCA = 0x10,
/* These need to be at the high end */
MasterOut = 0x800,
MonitorOut = 0x1000,
Auditioner = 0x2000,
/* These are for sharing Stripable states between the GUI and other
* user interfaces/control surfaces
*/
Selected = 0x4000,
Hidden = 0x8000,
/* single bit indicates that the group order is set */
GroupOrderSet = 0x100000000,
/* Masks */
GroupMask = (AudioTrack|MidiTrack|AudioBus|MidiBus|VCA),
SpecialMask = (MasterOut|MonitorOut|Auditioner),
StatusMask = (Selected|Hidden),
};
static const Flag Route;
static const Flag Track;
static const Flag Bus;
typedef uint32_t order_t;
typedef uint64_t global_order_t;
PresentationInfo (Flag f) : _order (0), _flags (Flag (f & ~GroupOrderSet)) { /* GroupOrderSet is not set */ }
PresentationInfo (order_t o, Flag f) : _order (o), _flags (Flag (f | GroupOrderSet)) { /* GroupOrderSet is set */ }
static const order_t max_order;
order_t group_order() const { return _order; }
global_order_t global_order () const {
if (_flags & Route) {
/* set all bits related to Route so that all Routes
sort together, with order() in the range of
64424509440..68719476735
Consider the following arrangement:
Track 1
Bus 1
Track 2
---------
VCA 1
---------
Master
---------
Monitor
these translate into the following
_order | _flags | order()
--------------------------------------
1 | 0x1 AudioTrack | ((0x1|0x2|0x4|0x8)<<32)|1 = 64424509441
2 | 0x2 AudioBus | ((0x1|0x2|0x4|0x8)<<32)|2 = 64424509442
3 | 0x1 AudioTrack | ((0x1|0x2|0x4|0x8)<<32)|3 = 64424509443
1 | 0x10 VCA | ((0x10)<<32)|1 = 68719476737
0 | 0x800 Master | (0x800<<32) = 8796093022208
0 | 0x1000 Monitor | (0x1000<<32) = 17592186044416
*/
return (((global_order_t) (_flags | Route)) << sizeof(order_t)) | _order;
} else {
return (((global_order_t) _flags) << sizeof(order_t)) | _order;
}
}
PresentationInfo::Flag flags() const { return _flags; }
bool order_set() const { return _order != 0; }
/* these objects have no defined order */
bool special () const { return _flags & SpecialMask; }
/* detect group order set/not set */
bool unordered() const { return !(_flags & GroupOrderSet); }
bool ordered() const { return _flags & GroupOrderSet; }
void set_flag (PresentationInfo::Flag f) {
_flags = PresentationInfo::Flag (_flags | f);
}
void unset_flag (PresentationInfo::Flag f) {
_flags = PresentationInfo::Flag (_flags & ~f);
}
void set_flags (Flag f) {
_flags = f;
}
bool flag_match (Flag f) const {
/* no flags, match all */
if (f == Flag (0)) {
return true;
}
if (f & StatusMask) {
/* status bits set, must match them */
if ((_flags & StatusMask) != (f & StatusMask)) {
return false;
}
}
/* Generic flags in f, match the right stuff */
if (f == Bus && (_flags & Bus)) {
/* some kind of bus */
return true;
}
if (f == Track && (_flags & Track)) {
/* some kind of track */
return true;
}
if (f == Route && (_flags & Route)) {
/* any kind of route */
return true;
}
return f == _flags;
}
std::string to_string () const;
uint64_t to_integer () const {
return ((uint64_t) _flags << sizeof(order_t)) | _order;
}
bool operator< (PresentationInfo const& other) const {
return global_order() < other.global_order();
}
PresentationInfo& operator= (std::string const& str) {
parse (str);
return *this;
}
bool match (PresentationInfo const& other) const {
return (_order == other.group_order()) && flag_match (other.flags());
}
bool operator==(PresentationInfo const& other) {
return (_order == other.group_order()) && (_flags == other.flags());
}
bool operator!=(PresentationInfo const& other) {
return (_order != other.group_order()) || (_flags != other.flags());
}
static Flag get_flags (XMLNode const& node);
protected:
friend class Stripable;
void set_group_order (order_t order) { _order = order; _flags = Flag (_flags|GroupOrderSet); }
private:
order_t _order;
Flag _flags;
PresentationInfo (std::string const & str);
int parse (std::string const&);
int parse (order_t, Flag f);
};
}
std::ostream& operator<<(std::ostream& o, ARDOUR::PresentationInfo const& rid);
#endif /* __libardour_presentation_info_h__ */

View File

@ -97,13 +97,7 @@ public:
typedef std::list<boost::shared_ptr<Processor> > ProcessorList;
enum Flag {
Auditioner = 0x1,
MasterOut = 0x2,
MonitorOut = 0x4
};
Route (Session&, std::string name, Flag flags = Flag(0), DataType default_type = DataType::AUDIO);
Route (Session&, std::string name, PresentationInfo::Flag flags = PresentationInfo::Flag(0), DataType default_type = DataType::AUDIO);
virtual ~Route();
virtual int init ();
@ -127,14 +121,6 @@ public:
bool set_name (const std::string& str);
static void set_name_in_state (XMLNode &, const std::string &, bool rename_playlist = true);
uint32_t order_key () const;
bool has_order_key () const;
void set_order_key (uint32_t);
bool is_auditioner() const { return _flags & Auditioner; }
bool is_master() const { return _flags & MasterOut; }
bool is_monitor() const { return _flags & MonitorOut; }
MonitorState monitoring_state () const;
virtual MeterState metering_state () const;
@ -569,28 +555,6 @@ public:
void protect_automation ();
enum {
/* These numbers are taken from MIDI Machine Control,
which can only control up to 317 tracks without
doing sysex segmentation.
*/
MasterBusRemoteControlID = 318,
MonitorBusRemoteControlID = 319,
};
void set_remote_control_id (uint32_t id, bool notify_class_listeners = true);
uint32_t remote_control_id () const;
void set_remote_control_id_explicit (uint32_t order_key);
/* for things concerned about *this* route's RID */
PBD::Signal0<void> RemoteControlIDChanged;
/* for things concerned about *any* route's RID changes */
static PBD::Signal0<void> RemoteControlIDChange;
static PBD::Signal0<void> SyncOrderKeys;
bool has_external_redirects() const;
/* can only be executed by a route for which is_monitor() is true
@ -663,7 +627,6 @@ public:
gint _pending_process_reorder; // atomic
gint _pending_signals; // atomic
Flag _flags;
int _pending_declick;
MeterPoint _meter_point;
MeterPoint _pending_meter_point;
@ -718,16 +681,12 @@ protected:
boost::shared_ptr<Processor> the_instrument_unlocked() const;
private:
private:
int64_t _track_number;
int set_state_2X (const XMLNode&, int);
void set_processor_state_2X (XMLNodeList const &, int);
uint32_t _order_key;
bool _has_order_key;
uint32_t _remote_control_id;
int64_t _track_number;
void input_change_handler (IOChange, void *src);
void output_change_handler (IOChange, void *src);
void sidechain_change_handler (IOChange, void *src);
@ -810,7 +769,6 @@ private:
void reset_instrument_info ();
void set_remote_control_id_internal (uint32_t id, bool notify_class_listeners = true);
void solo_control_changed (bool self, PBD::Controllable::GroupControlDisposition);
};

View File

@ -1,44 +0,0 @@
/*
Copyright (C) 2000-2014 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __libardour_route_sorters_h__
#define __libardour_route_sorters_h__
#include "ardour/route.h"
namespace ARDOUR {
struct SignalOrderRouteSorter {
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
if (a->is_master() || a->is_monitor()) {
/* "a" is a special route (master, monitor, etc), and comes
* last in the mixer ordering
*/
return false;
} else if (b->is_master() || b->is_monitor()) {
/* everything comes before b */
return true;
}
return a->order_key () < b->order_key ();
}
};
} // namespace
#endif /* __libardour_route_sorters_h__ */

View File

@ -64,11 +64,13 @@
#include "ardour/luascripting.h"
#include "ardour/location.h"
#include "ardour/monitor_processor.h"
#include "ardour/presentation_info.h"
#include "ardour/rc_configuration.h"
#include "ardour/session_configuration.h"
#include "ardour/session_event.h"
#include "ardour/interpolation.h"
#include "ardour/plugin.h"
#include "ardour/presentation_info.h"
#include "ardour/route.h"
#include "ardour/route_graph.h"
@ -215,8 +217,6 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
PBD::Signal0<void> DirtyChanged;
PBD::Signal1<void, bool> RouteAddedOrRemoved;
const SessionDirectory& session_directory () const { return *(_session_dir.get()); }
static PBD::Signal1<void,std::string> Dialog;
@ -293,22 +293,20 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
bool operator() (boost::shared_ptr<Route>, boost::shared_ptr<Route> b);
};
void set_order_hint (int32_t order_hint) {_order_hint = order_hint;};
void notify_remote_id_change ();
void sync_order_keys ();
void notify_presentation_info_change ();
template<class T> void foreach_route (T *obj, void (T::*func)(Route&), bool sort = true);
template<class T> void foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>), bool sort = true);
template<class T, class A> void foreach_route (T *obj, void (T::*func)(Route&, A), A arg, bool sort = true);
static char session_name_is_legal (const std::string&);
bool io_name_is_legal (const std::string&);
boost::shared_ptr<Route> route_by_name (std::string);
boost::shared_ptr<Route> route_by_id (PBD::ID);
boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
boost::shared_ptr<Stripable> stripable_by_remote_id (uint32_t id);
boost::shared_ptr<Route> route_by_selected_count (uint32_t cnt);
boost::shared_ptr<Track> track_by_diskstream_id (PBD::ID);
bool io_name_is_legal (const std::string&) const;
boost::shared_ptr<Route> route_by_name (std::string) const;
boost::shared_ptr<Route> route_by_id (PBD::ID) const;
boost::shared_ptr<Stripable> get_remote_nth_stripable (uint16_t n, PresentationInfo::Flag) const;
boost::shared_ptr<Route> get_remote_nth_route (uint16_t n) const;
boost::shared_ptr<Route> route_by_selected_count (uint32_t cnt) const;
boost::shared_ptr<Track> track_by_diskstream_id (PBD::ID) const;
void routes_using_input_from (const std::string& str, RouteList& rl);
bool route_name_unique (std::string) const;
@ -595,29 +593,24 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
std::list<boost::shared_ptr<AudioTrack> > new_audio_track (
int input_channels,
int output_channels,
TrackMode mode = Normal,
RouteGroup* route_group = 0,
uint32_t how_many = 1,
std::string name_template = ""
);
RouteList new_audio_route (
int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, std::string name_template = ""
RouteGroup* route_group,
uint32_t how_many,
std::string name_template,
PresentationInfo::order_t order,
TrackMode mode = Normal
);
std::list<boost::shared_ptr<MidiTrack> > new_midi_track (
const ChanCount& input, const ChanCount& output,
boost::shared_ptr<PluginInfo> instrument = boost::shared_ptr<PluginInfo>(),
TrackMode mode = Normal,
RouteGroup* route_group = 0, uint32_t how_many = 1, std::string name_template = "",
Plugin::PresetRecord* pset = 0
boost::shared_ptr<PluginInfo> instrument,
Plugin::PresetRecord* pset = 0,
RouteGroup* route_group, uint32_t how_many, std::string name_template,
PresentationInfo::order_t,
TrackMode mode = Normal
);
RouteList new_midi_route (RouteGroup* route_group,
uint32_t how_many,
std::string name_template = "",
boost::shared_ptr<PluginInfo> instrument = boost::shared_ptr<PluginInfo>(),
Plugin::PresetRecord* pset = 0);
RouteList new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, std::string name_template, PresentationInfo::Flag, PresentationInfo::order_t);
RouteList new_midi_route (RouteGroup* route_group, uint32_t how_many, std::string name_template, boost::shared_ptr<PluginInfo> instrument, Plugin::PresetRecord*, PresentationInfo::Flag, PresentationInfo::order_t);
void remove_routes (boost::shared_ptr<RouteList>);
void remove_route (boost::shared_ptr<Route>);
@ -1658,8 +1651,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
SerializedRCUManager<RouteList> routes;
void add_routes (RouteList&, bool input_auto_connect, bool output_auto_connect, bool save);
void add_routes_inner (RouteList&, bool input_auto_connect, bool output_auto_connect);
void add_routes (RouteList&, bool input_auto_connect, bool output_auto_connect, bool save, PresentationInfo::order_t);
void add_routes_inner (RouteList&, bool input_auto_connect, bool output_auto_connect, PresentationInfo::order_t);
bool _adding_routes_in_progress;
bool _reconnecting_routes_in_progress;
bool _route_deletion_in_progress;
@ -1976,8 +1969,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
*/
GraphEdges _current_route_graph;
uint32_t next_control_id () const;
int32_t _order_hint;
void ensure_presentation_info_gap (PresentationInfo::order_t, uint32_t gap_size);
bool ignore_route_processor_changes;
MidiClockTicker* midi_clock;
@ -2005,6 +1997,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
std::string _template_state_dir;
VCAManager* _vca_manager;
boost::shared_ptr<Route> get_midi_nth_route_by_id (PresentationInfo::order_t n) const;
};

View File

@ -26,7 +26,11 @@
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
#include "pbd/signals.h"
#include "ardour/presentation_info.h"
#include "ardour/session_object.h"
#include "ardour/libardour_visibility.h"
namespace ARDOUR {
@ -46,18 +50,44 @@ class MonitorControl;
* and behaviour of the object.
*/
class Stripable : public SessionObject {
class LIBARDOUR_API Stripable : public SessionObject {
public:
Stripable (Session& session, const std::string& name)
: SessionObject (session, name) {}
Stripable (Session& session, std::string const & name, PresentationInfo const &);
virtual ~Stripable () {}
/* XXX
midi on/off
selected status
visible/hidden
*/
virtual uint32_t remote_control_id () const = 0;
bool is_auditioner() const { return _presentation_info.flags() & PresentationInfo::Auditioner; }
bool is_master() const { return _presentation_info.flags() & PresentationInfo::MasterOut; }
bool is_monitor() const { return _presentation_info.flags() & PresentationInfo::MonitorOut; }
int set_state (XMLNode const&, int);
bool is_hidden() const { return _presentation_info.flags() & PresentationInfo::Hidden; }
bool is_selected() const { return _presentation_info.flags() & PresentationInfo::Selected; }
PresentationInfo const & presentation_info () const { return _presentation_info; }
PresentationInfo& presentation_info () { return _presentation_info; }
/* set just the order */
void set_presentation_group_order (PresentationInfo::order_t, bool notify_class_listeners = true);
void set_presentation_group_order_explicit (PresentationInfo::order_t);
/* for things concerned about *this* route's RID */
PBD::Signal0<void> PresentationInfoChanged;
/* for things concerned about *any* route's RID changes */
static PBD::Signal0<void> PresentationInfoChange;
/***************************************************************
* Pure interface begins here
***************************************************************/
virtual boost::shared_ptr<PeakMeter> peak_meter() = 0;
virtual boost::shared_ptr<const PeakMeter> peak_meter() const = 0;
@ -140,6 +170,28 @@ class Stripable : public SessionObject {
virtual boost::shared_ptr<AutomationControl> master_send_enable_controllable () const = 0;
virtual bool muted_by_others_soloing () const = 0;
protected:
PresentationInfo _presentation_info;
/* set the entire info. This should only be used in cases where the
* derived could not supply the correct Flag and/or order information
* in its constructor.
*/
void set_presentation_info (PresentationInfo id, bool notify_class_listeners = true);
void set_presentation_info_explicit (PresentationInfo);
void add_state (XMLNode&) const;
private:
void set_presentation_info_internal (PresentationInfo id, bool notify_class_listeners = true);
};
struct PresentationInfoSorter {
bool operator() (boost::shared_ptr<Stripable> a, boost::shared_ptr<Stripable> b) {
return a->presentation_info() < b->presentation_info();
}
};

View File

@ -45,7 +45,7 @@ class MonitorControl;
class LIBARDOUR_API Track : public Route, public Recordable, public PublicDiskstream
{
public:
Track (Session&, std::string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal, DataType default_type = DataType::AUDIO);
Track (Session&, std::string name, PresentationInfo::Flag f = PresentationInfo::Flag (0), TrackMode m = Normal, DataType default_type = DataType::AUDIO);
virtual ~Track ();
int init ();

View File

@ -50,8 +50,8 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
: Track (sess, name, flag, mode)
AudioTrack::AudioTrack (Session& sess, string name, TrackMode mode)
: Track (sess, name, PresentationInfo::AudioTrack, mode)
{
}

View File

@ -46,7 +46,7 @@ using namespace PBD;
#include "i18n.h"
Auditioner::Auditioner (Session& s)
: Track (s, "auditioner", Route::Auditioner)
: Track (s, "auditioner", PresentationInfo::Auditioner)
, current_frame (0)
, _auditioning (0)
, length (0)

View File

@ -32,6 +32,7 @@
#include "ardour/location.h"
#include "ardour/midi_model.h"
#include "ardour/mute_master.h"
#include "ardour/presentation_info.h"
#include "ardour/session.h"
#include "ardour/source.h"
#include "ardour/tempo.h"
@ -99,7 +100,6 @@ setup_enum_writer ()
AutoConnectOption _AutoConnectOption;
TracksAutoNamingRule _TracksAutoNamingRule;
Session::StateOfTheState _Session_StateOfTheState;
Route::Flag _Route_Flag;
Source::Flag _Source_Flag;
Diskstream::Flag _Diskstream_Flag;
Location::Flags _Location_Flags;
@ -134,6 +134,7 @@ setup_enum_writer ()
Evoral::OverlapType _OverlapType;
BufferingPreset _BufferingPreset;
AutoReturnTarget _AutoReturnTarget;
PresentationInfo::Flag _PresentationInfo_Flag;
#define REGISTER(e) enum_writer.register_distinct (typeid(e).name(), i, s); i.clear(); s.clear()
#define REGISTER_BITS(e) enum_writer.register_bits (typeid(e).name(), i, s); i.clear(); s.clear()
@ -491,11 +492,6 @@ setup_enum_writer ()
REGISTER_CLASS_ENUM (Session, pullup_Minus4Minus1);
REGISTER (_Session_PullupFormat);
REGISTER_CLASS_ENUM (Route, Auditioner);
REGISTER_CLASS_ENUM (Route, MasterOut);
REGISTER_CLASS_ENUM (Route, MonitorOut);
REGISTER_BITS (_Route_Flag);
REGISTER_CLASS_ENUM (Source, Writable);
REGISTER_CLASS_ENUM (Source, CanRename);
REGISTER_CLASS_ENUM (Source, Broadcast);
@ -709,6 +705,20 @@ setup_enum_writer ()
REGISTER_ENUM (Loop);
REGISTER_ENUM (RegionSelectionStart);
REGISTER_BITS (_AutoReturnTarget);
REGISTER_CLASS_ENUM (PresentationInfo, AudioTrack);
REGISTER_CLASS_ENUM (PresentationInfo, MidiTrack);
REGISTER_CLASS_ENUM (PresentationInfo, AudioBus);
REGISTER_CLASS_ENUM (PresentationInfo, MidiBus);
REGISTER_CLASS_ENUM (PresentationInfo, MasterOut);
REGISTER_CLASS_ENUM (PresentationInfo, MonitorOut);
REGISTER_CLASS_ENUM (PresentationInfo, VCA);
REGISTER_CLASS_ENUM (PresentationInfo, Bus);
REGISTER_CLASS_ENUM (PresentationInfo, Track);
REGISTER_CLASS_ENUM (PresentationInfo, Route);
REGISTER_CLASS_ENUM (PresentationInfo, Selected);
REGISTER_CLASS_ENUM (PresentationInfo, Hidden);
REGISTER (_PresentationInfo_Flag);
}
} /* namespace ARDOUR */

View File

@ -1033,7 +1033,7 @@ LuaBindings::common (lua_State* L)
.addFunction ("record_status", &Session::record_status)
.addFunction ("route_by_id", &Session::route_by_id)
.addFunction ("route_by_name", &Session::route_by_name)
.addFunction ("route_by_remote_id", &Session::route_by_remote_id)
// STRIPABLE .addFunction ("route_by_remote_id", &Session::route_by_remote_id)
.addFunction ("track_by_diskstream_id", &Session::track_by_diskstream_id)
.addFunction ("source_by_id", &Session::source_by_id)
.addFunction ("controllable_by_id", &Session::controllable_by_id)

View File

@ -67,8 +67,8 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
: Track (sess, name, flag, mode, DataType::MIDI)
MidiTrack::MidiTrack (Session& sess, string name, TrackMode mode)
: Track (sess, name, PresentationInfo::MidiTrack, mode, DataType::MIDI)
, _immediate_events(1024) // FIXME: size?
, _step_edit_ring_buffer(64) // FIXME: size?
, _note_mode(Sustained)

View File

@ -0,0 +1,121 @@
/*
Copyright (C) 2016 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <sstream>
#include <typeinfo>
#include <cassert>
#include "pbd/enumwriter.h"
#include "pbd/error.h"
#include "pbd/failed_constructor.h"
#include "pbd/xml++.h"
#include "ardour/presentation_info.h"
#include "i18n.h"
using namespace ARDOUR;
using namespace PBD;
using std::string;
const PresentationInfo::order_t PresentationInfo::max_order = UINT32_MAX;
const PresentationInfo::Flag PresentationInfo::Bus = PresentationInfo::Flag (PresentationInfo::AudioBus|PresentationInfo::MidiBus);
const PresentationInfo::Flag PresentationInfo::Track = PresentationInfo::Flag (PresentationInfo::AudioTrack|PresentationInfo::MidiTrack);
const PresentationInfo::Flag PresentationInfo::Route = PresentationInfo::Flag (PresentationInfo::Bus|PresentationInfo::Track);
PresentationInfo::PresentationInfo (std::string const & str)
{
if (parse (str)) {
throw failed_constructor ();
}
}
int
PresentationInfo::parse (string const& str)
{
std::stringstream s (str);
/* new school, segmented string "NNN:TYPE" */
string f;
char c;
s >> _order;
/* skip colon */
s >> c;
/* grab flags */
s >> f;
_flags = Flag (string_2_enum (f, _flags)|GroupOrderSet);
std::cerr << "Parsed [" << str << "] as " << _order << " + " << enum_2_string (_flags) << std::endl;
return 0;
}
int
PresentationInfo::parse (uint32_t n, Flag f)
{
if (n < UINT16_MAX) {
assert (f != Flag (0));
_order = n;
_flags = Flag (f|GroupOrderSet);
} else {
_order = (n & 0xffff);
_flags = Flag ((n >> 16)|GroupOrderSet);
}
return 0;
}
std::string
PresentationInfo::to_string() const
{
std::stringstream ss;
/* Do not save or selected hidden status, or group-order set bit */
Flag f = Flag (_flags & ~(Hidden|Selected|GroupOrderSet));
ss << _order << ':' << enum_2_string (f);
return ss.str();
}
PresentationInfo::Flag
PresentationInfo::get_flags (XMLNode const& node)
{
const XMLProperty *prop;
XMLNodeList nlist = node.children ();
XMLNodeConstIterator niter;
XMLNode *child;
for (niter = nlist.begin(); niter != nlist.end(); ++niter){
child = *niter;
if (child->name() == X_("PresentationInfo")) {
if ((prop = child->property (X_("value"))) != 0) {
PresentationInfo pi (prop->value());
return pi.flags ();
}
}
}
return Flag (0);
}
std::ostream&
operator<<(std::ostream& o, ARDOUR::PresentationInfo const& rid)
{
return o << rid.to_string ();
}

View File

@ -80,14 +80,12 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
PBD::Signal0<void> Route::SyncOrderKeys;
PBD::Signal0<void> Route::RemoteControlIDChange;
PBD::Signal3<int,boost::shared_ptr<Route>, boost::shared_ptr<PluginInsert>, Route::PluginSetupOptions > Route::PluginSetup;
/** Base class for all routable/mixable objects (tracks and busses) */
Route::Route (Session& sess, string name, Flag flg, DataType default_type)
Route::Route (Session& sess, string name, PresentationInfo::Flag flag, DataType default_type)
: GraphNode (sess._process_graph)
, Stripable (sess, name)
, Stripable (sess, name, PresentationInfo (flag))
, Muteable (sess, name)
, Automatable (sess)
, _active (true)
@ -98,7 +96,6 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type)
, _roll_delay (0)
, _pending_process_reorder (0)
, _pending_signals (0)
, _flags (flg)
, _pending_declick (true)
, _meter_point (MeterPostFader)
, _pending_meter_point (MeterPostFader)
@ -109,10 +106,6 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type)
, _declickable (false)
, _have_internal_generator (false)
, _default_type (default_type)
, _order_key (0)
, _has_order_key (false)
, _remote_control_id (0)
, _track_number (0)
, _in_configure_processors (false)
, _initial_io_setup (false)
, _in_sidechain_setup (false)
@ -162,7 +155,7 @@ Route::init ()
/* panning */
if (!(_flags & Route::MonitorOut)) {
if (!(_presentation_info.flags() & PresentationInfo::MonitorOut)) {
_pannable.reset (new Pannable (_session));
}
@ -270,120 +263,6 @@ Route::~Route ()
_processors.clear ();
}
void
Route::set_remote_control_id (uint32_t id, bool notify_class_listeners)
{
if (Config->get_remote_model() != UserOrdered) {
return;
}
set_remote_control_id_internal (id, notify_class_listeners);
}
void
Route::set_remote_control_id_internal (uint32_t id, bool notify_class_listeners)
{
/* force IDs for master/monitor busses and prevent
any other route from accidentally getting these IDs
(i.e. legacy sessions)
*/
if (is_master() && id != MasterBusRemoteControlID) {
id = MasterBusRemoteControlID;
}
if (is_monitor() && id != MonitorBusRemoteControlID) {
id = MonitorBusRemoteControlID;
}
if (id < 1) {
return;
}
/* don't allow it to collide */
if (!is_master () && !is_monitor() &&
(id == MasterBusRemoteControlID || id == MonitorBusRemoteControlID)) {
id += MonitorBusRemoteControlID;
}
if (id != remote_control_id()) {
_remote_control_id = id;
RemoteControlIDChanged ();
if (notify_class_listeners) {
RemoteControlIDChange ();
}
}
}
uint32_t
Route::remote_control_id() const
{
if (is_master()) {
return MasterBusRemoteControlID;
}
if (is_monitor()) {
return MonitorBusRemoteControlID;
}
return _remote_control_id;
}
bool
Route::has_order_key () const
{
return _has_order_key;
}
uint32_t
Route::order_key () const
{
return _order_key;
}
void
Route::set_remote_control_id_explicit (uint32_t rid)
{
if (is_master() || is_monitor() || is_auditioner()) {
/* hard-coded remote IDs, or no remote ID */
return;
}
if (_remote_control_id != rid) {
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1: set edit-based RID to %2\n", name(), rid));
_remote_control_id = rid;
RemoteControlIDChanged (); /* EMIT SIGNAL (per-route) */
}
/* don't emit the class-level RID signal RemoteControlIDChange here,
leave that to the entity that changed the order key, so that we
don't get lots of emissions for no good reasons (e.g. when changing
all route order keys).
See Session::sync_remote_id_from_order_keys() for the (primary|only)
spot where that is emitted.
*/
}
void
Route::set_order_key (uint32_t n)
{
_has_order_key = true;
if (_order_key == n) {
return;
}
_order_key = n;
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1 order key set to %2\n",
name(), order_key ()));
_session.set_dirty ();
}
string
Route::ensure_track_or_route_name(string name, Session &session)
{
@ -2357,9 +2236,7 @@ Route::state(bool full_state)
node->add_property("default-type", _default_type.to_string());
node->add_property ("strict-io", _strict_io);
if (_flags) {
node->add_property("flags", enum_2_string (_flags));
}
Stripable::add_state (*node);
node->add_property("active", _active?"yes":"no");
string p;
@ -2372,9 +2249,6 @@ Route::state(bool full_state)
node->add_property("route-group", _route_group->name());
}
snprintf (buf, sizeof (buf), "%d", _order_key);
node->add_property ("order-key", buf);
node->add_child_nocopy (_solo_control->get_state ());
node->add_child_nocopy (_solo_isolate_control->get_state ());
node->add_child_nocopy (_solo_safe_control->get_state ());
@ -2390,11 +2264,6 @@ Route::state(bool full_state)
node->add_child_nocopy (Automatable::get_automation_xml_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 (_comment.length()) {
XMLNode *cmt = node->add_child ("Comment");
cmt->add_content (_comment);
@ -2474,11 +2343,7 @@ Route::set_state (const XMLNode& node, int version)
set_id (node);
_initial_io_setup = true;
if ((prop = node.property (X_("flags"))) != 0) {
_flags = Flag (string_2_enum (prop->value(), _flags));
} else {
_flags = Flag (0);
}
Stripable::set_state (node, version);
if ((prop = node.property (X_("strict-io"))) != 0) {
_strict_io = string_is_affirmative (prop->value());
@ -2575,46 +2440,6 @@ Route::set_state (const XMLNode& node, int version)
set_active (yn, this);
}
if ((prop = node.property (X_("order-key"))) != 0) { // New order key (no separate mixer/editor ordering)
set_order_key (atoi(prop->value()));
}
if ((prop = node.property (X_("order-keys"))) != 0) { // Deprecated order keys
int32_t n;
string::size_type colon, equal;
string remaining = prop->value();
while (remaining.length()) {
if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
<< endmsg;
} else {
if (sscanf (remaining.substr (equal+1).c_str(), "%d", &n) != 1) {
error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
<< endmsg;
} else {
string keyname = remaining.substr (0, equal);
if ((keyname == "EditorSort") || (keyname == "editor")) {
cerr << "Setting " << name() << " order key to " << n << " using saved Editor order." << endl;
set_order_key (n);
}
}
}
colon = remaining.find_first_of (':');
if (colon != string::npos) {
remaining = remaining.substr (colon+1);
} else {
break;
}
}
}
if ((prop = node.property (X_("processor-after-last-custom-meter"))) != 0) {
PBD::ID id (prop->value ());
Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
@ -2646,13 +2471,6 @@ Route::set_state (const XMLNode& node, int version)
_mute_control->set_state (*child, version);
}
} else if (child->name() == X_("RemoteControl")) {
if ((prop = child->property (X_("id"))) != 0) {
int32_t x;
sscanf (prop->value().c_str(), "%d", &x);
set_remote_control_id_internal (x);
}
} else if (child->name() == MuteMaster::xml_node_name) {
_mute_master->set_state (*child, version);
@ -2684,13 +2502,7 @@ Route::set_state_2X (const XMLNode& node, int version)
return -1;
}
if ((prop = node.property (X_("flags"))) != 0) {
string f = prop->value ();
boost::replace_all (f, "ControlOut", "MonitorOut");
_flags = Flag (string_2_enum (f, _flags));
} else {
_flags = Flag (0);
}
Stripable::set_state (node, version);
if (is_master() || is_monitor() || is_auditioner()) {
_mute_master->set_solo_ignore (true);
@ -2764,46 +2576,6 @@ Route::set_state_2X (const XMLNode& node, int version)
_meter_point = MeterPoint (string_2_enum (prop->value (), _meter_point));
}
/* do not carry over edit/mix groups from 2.X because (a) its hard (b) they
don't mean the same thing.
*/
if ((prop = node.property (X_("order-keys"))) != 0) {
int32_t n;
string::size_type colon, equal;
string remaining = prop->value();
while (remaining.length()) {
if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
<< endmsg;
} else {
if (sscanf (remaining.substr (equal+1).c_str(), "%d", &n) != 1) {
error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
<< endmsg;
} else {
string keyname = remaining.substr (0, equal);
if (keyname == "EditorSort" || keyname == "editor") {
info << string_compose(_("Converting deprecated order key for %1 using Editor order %2"), name (), n) << endmsg;
set_order_key (n);
}
}
}
colon = remaining.find_first_of (':');
if (colon != string::npos) {
remaining = remaining.substr (colon+1);
} else {
break;
}
}
}
/* IOs */
nlist = node.children ();
@ -2893,13 +2665,6 @@ Route::set_state_2X (const XMLNode& node, int version)
_mute_control->set_state (*child, version);
}
} else if (child->name() == X_("RemoteControl")) {
if ((prop = child->property (X_("id"))) != 0) {
int32_t x;
sscanf (prop->value().c_str(), "%d", &x);
set_remote_control_id_internal (x);
}
}
}

View File

@ -198,11 +198,13 @@ struct RouteRecEnabledComparator
{
boost::shared_ptr<Track> t1 (boost::dynamic_pointer_cast<Track>(r1));
boost::shared_ptr<Track> t2 (boost::dynamic_pointer_cast<Track>(r2));
PresentationInfo::global_order_t r1o = r1->presentation_info().global_order();
PresentationInfo::global_order_t r2o = r2->presentation_info().global_order();
if (!t1) {
if (!t2) {
/* makes no difference which is first, use signal order */
return r1->order_key () < r2->order_key ();
/* makes no difference which is first, use presentation order */
return r1o < r2o;
} else {
/* r1 is not a track, r2 is, run it early */
return false;
@ -210,14 +212,14 @@ struct RouteRecEnabledComparator
}
if (!t2) {
/* we already tested !t1, so just use signal order */
return r1->order_key () < r2->order_key ();
/* we already tested !t1, so just use presentation order */
return r1o < r2o;
}
if (t1->rec_enable_control()->get_value()) {
if (t2->rec_enable_control()->get_value()) {
/* both rec-enabled, just use signal order */
return t1->order_key () < t2->order_key ();
return r1o < r2o;
} else {
/* t1 rec-enabled, t2 not rec-enabled, run t2 early */
return false;
@ -227,8 +229,8 @@ struct RouteRecEnabledComparator
/* t2 rec-enabled, t1 not rec-enabled, run t1 early */
return true;
} else {
/* neither rec-enabled, use signal order */
return t1->order_key () < t2->order_key ();
/* neither rec-enabled, use presentation order */
return r1o < r2o;
}
}
}

View File

@ -473,7 +473,7 @@ RouteGroup::make_subgroup (bool aux, Placement placement)
* (since tracks can't have fewer outs than ins,
* "nin" currently defines the number of outpus if nin > 2)
*/
rl = _session.new_audio_route (nin, 2 /*XXX*/, 0, 1);
rl = _session.new_audio_route (nin, 2, 0, 1, string(), PresentationInfo::AudioBus, PresentationInfo::max_order);
} catch (...) {
return;
}

View File

@ -92,7 +92,6 @@
#include "ardour/region_factory.h"
#include "ardour/route_graph.h"
#include "ardour/route_group.h"
#include "ardour/route_sorters.h"
#include "ardour/send.h"
#include "ardour/session.h"
#include "ardour/session_directory.h"
@ -308,7 +307,6 @@ Session::Session (AudioEngine &eng,
, _step_editors (0)
, _suspend_timecode_transmission (0)
, _speakers (new Speakers)
, _order_hint (-1)
, ignore_route_processor_changes (false)
, midi_clock (0)
, _scene_changer (0)
@ -1149,7 +1147,7 @@ Session::add_monitor_section ()
return;
}
boost::shared_ptr<Route> r (new Route (*this, _("Monitor"), Route::MonitorOut, DataType::AUDIO));
boost::shared_ptr<Route> r (new Route (*this, _("Monitor"), PresentationInfo::MonitorOut, DataType::AUDIO));
if (r->init ()) {
return;
@ -1167,7 +1165,7 @@ Session::add_monitor_section ()
}
rl.push_back (r);
add_routes (rl, false, false, false);
add_routes (rl, false, false, false, 0);
assert (_monitor_out);
@ -2307,8 +2305,7 @@ Session::resort_routes_using (boost::shared_ptr<RouteList> r)
#ifndef NDEBUG
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 ()));
DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 presentation order %2\n", (*i)->name(), (*i)->presentation_info().global_order()));
}
#endif
@ -2426,8 +2423,9 @@ Session::default_track_name_pattern (DataType t)
* @param instrument plugin info for the instrument to insert pre-fader, if any
*/
list<boost::shared_ptr<MidiTrack> >
Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost::shared_ptr<PluginInfo> instrument,
TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template, Plugin::PresetRecord* pset)
Session::new_midi_track (boost::shared_ptr<PluginInfo> instrument, Plugin::PresetRecord* pset,
RouteGroup* route_group, uint32_t how_many, string name_template, PresentationInfo::order_t order,
TrackMode mode)
{
string track_name;
uint32_t track_id = 0;
@ -2447,7 +2445,7 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost:
boost::shared_ptr<MidiTrack> track;
try {
track.reset (new MidiTrack (*this, track_name, Route::Flag (0), mode));
track.reset (new MidiTrack (*this, track_name, mode));
if (track->init ()) {
goto failed;
@ -2482,14 +2480,8 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost:
track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
if (Config->get_remote_model() == UserOrdered) {
track->set_remote_control_id (next_control_id());
}
new_routes.push_back (track);
ret.push_back (track);
RouteAddedOrRemoved (true); /* EMIT SIGNAL */
}
catch (failed_constructor &err) {
@ -2510,9 +2502,9 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost:
if (!new_routes.empty()) {
StateProtector sp (this);
if (Profile->get_trx()) {
add_routes (new_routes, false, false, false);
add_routes (new_routes, false, false, false, order);
} else {
add_routes (new_routes, true, true, false);
add_routes (new_routes, true, true, false, order);
}
if (instrument) {
@ -2532,7 +2524,8 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost:
}
RouteList
Session::new_midi_route (RouteGroup* route_group, uint32_t how_many, string name_template, boost::shared_ptr<PluginInfo> instrument, Plugin::PresetRecord* pset)
Session::new_midi_route (RouteGroup* route_group, uint32_t how_many, string name_template, boost::shared_ptr<PluginInfo> instrument, Plugin::PresetRecord* pset,
PresentationInfo::Flag flag, PresentationInfo::order_t order)
{
string bus_name;
uint32_t bus_id = 0;
@ -2546,9 +2539,9 @@ Session::new_midi_route (RouteGroup* route_group, uint32_t how_many, string name
error << "cannot find name for new midi bus" << endmsg;
goto failure;
}
try {
boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO)); // XXX Editor::add_routes is not ready for ARDOUR::DataType::MIDI
boost::shared_ptr<Route> bus (new Route (*this, bus_name, flag, DataType::AUDIO)); // XXX Editor::add_routes is not ready for ARDOUR::DataType::MIDI
if (bus->init ()) {
goto failure;
@ -2578,13 +2571,8 @@ Session::new_midi_route (RouteGroup* route_group, uint32_t how_many, string name
if (route_group) {
route_group->add (bus);
}
if (Config->get_remote_model() == UserOrdered) {
bus->set_remote_control_id (next_control_id());
}
ret.push_back (bus);
RouteAddedOrRemoved (true); /* EMIT SIGNAL */
ARDOUR::GUIIdle ();
}
catch (failed_constructor &err) {
@ -2604,7 +2592,7 @@ Session::new_midi_route (RouteGroup* route_group, uint32_t how_many, string name
failure:
if (!ret.empty()) {
StateProtector sp (this);
add_routes (ret, false, false, false);
add_routes (ret, false, false, false, order);
if (instrument) {
for (RouteList::iterator r = ret.begin(); r != ret.end(); ++r) {
@ -2931,12 +2919,36 @@ Session::reconnect_mmc_ports(bool inputs)
#endif
void
Session::ensure_presentation_info_gap (PresentationInfo::order_t first_new_order, uint32_t how_many)
{
if (first_new_order == PresentationInfo::max_order) {
/* adding at end, no worries */
return;
}
/* create a gap in the existing route order keys to accomodate new routes.*/
boost::shared_ptr <RouteList> rd = routes.reader();
for (RouteList::iterator ri = rd->begin(); ri != rd->end(); ++ri) {
boost::shared_ptr<Route> rt (*ri);
if (rt->presentation_info().special()) {
continue;
}
if (rt->presentation_info().group_order () >= first_new_order) {
rt->set_presentation_group_order (rt->presentation_info().group_order () + how_many);
}
}
}
/** Caller must not hold process lock
* @param name_template string to use for the start of the name, or "" to use "Audio".
*/
list< boost::shared_ptr<AudioTrack> >
Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group,
uint32_t how_many, string name_template)
Session::new_audio_track (int input_channels, int output_channels, RouteGroup* route_group,
uint32_t how_many, string name_template, PresentationInfo::order_t order,
TrackMode mode)
{
string track_name;
uint32_t track_id = 0;
@ -2957,7 +2969,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
boost::shared_ptr<AudioTrack> track;
try {
track.reset (new AudioTrack (*this, track_name, Route::Flag (0), mode));
track.reset (new AudioTrack (*this, track_name, mode));
if (track->init ()) {
goto failed;
@ -2967,7 +2979,6 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
track->set_strict_io (true);
}
if (ARDOUR::Profile->get_trx ()) {
// TRACKS considers it's not a USE CASE, it's
// a piece of behavior of the session model:
@ -3013,14 +3024,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));
if (Config->get_remote_model() == UserOrdered) {
track->set_remote_control_id (next_control_id());
}
new_routes.push_back (track);
ret.push_back (track);
RouteAddedOrRemoved (true); /* EMIT SIGNAL */
}
catch (failed_constructor &err) {
@ -3041,9 +3047,9 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
if (!new_routes.empty()) {
StateProtector sp (this);
if (Profile->get_trx()) {
add_routes (new_routes, false, false, false);
add_routes (new_routes, false, false, false, order);
} else {
add_routes (new_routes, true, true, false);
add_routes (new_routes, true, true, false, order);
}
}
@ -3054,7 +3060,8 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
* @param name_template string to use for the start of the name, or "" to use "Bus".
*/
RouteList
Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template)
Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template,
PresentationInfo::Flag flags, PresentationInfo::order_t order)
{
string bus_name;
uint32_t bus_id = 0;
@ -3063,6 +3070,8 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r
bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
ensure_presentation_info_gap (order, how_many);
while (how_many) {
if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, use_number)) {
error << "cannot find name for new audio bus" << endmsg;
@ -3070,7 +3079,7 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r
}
try {
boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
boost::shared_ptr<Route> bus (new Route (*this, bus_name, flags, DataType::AUDIO));
if (bus->init ()) {
goto failure;
@ -3104,20 +3113,11 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r
if (route_group) {
route_group->add (bus);
}
if (Config->get_remote_model() == UserOrdered) {
bus->set_remote_control_id (next_control_id());
}
bus->add_internal_return ();
ret.push_back (bus);
RouteAddedOrRemoved (true); /* EMIT SIGNAL */
ARDOUR::GUIIdle ();
}
catch (failed_constructor &err) {
error << _("Session: could not create new audio route.") << endmsg;
goto failure;
@ -3136,9 +3136,9 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r
if (!ret.empty()) {
StateProtector sp (this);
if (Profile->get_trx()) {
add_routes (ret, false, false, false);
add_routes (ret, false, false, false, order);
} else {
add_routes (ret, false, true, true); // autoconnect // outputs only
add_routes (ret, false, true, true, order); // autoconnect // outputs only
}
}
@ -3162,7 +3162,6 @@ RouteList
Session::new_route_from_template (uint32_t how_many, XMLNode& node, const std::string& name_base, PlaylistDisposition pd)
{
RouteList ret;
uint32_t control_id;
uint32_t number = 0;
const uint32_t being_added = how_many;
/* This will prevent the use of any existing XML-provided PBD::ID
@ -3171,8 +3170,6 @@ Session::new_route_from_template (uint32_t how_many, XMLNode& node, const std::s
Stateful::ForceIDRegeneration force_ids;
IO::disable_connecting ();
control_id = next_control_id ();
while (how_many) {
/* We're going to modify the node contents a bit so take a
@ -3293,9 +3290,6 @@ Session::new_route_from_template (uint32_t how_many, XMLNode& node, const std::s
route->output()->changed (change, this);
}
route->set_remote_control_id (control_id);
++control_id;
boost::shared_ptr<Track> track;
if ((track = boost::dynamic_pointer_cast<Track> (route))) {
@ -3312,8 +3306,6 @@ Session::new_route_from_template (uint32_t how_many, XMLNode& node, const std::s
};
ret.push_back (route);
RouteAddedOrRemoved (true); /* EMIT SIGNAL */
}
catch (failed_constructor &err) {
@ -3333,9 +3325,9 @@ Session::new_route_from_template (uint32_t how_many, XMLNode& node, const std::s
if (!ret.empty()) {
StateProtector sp (this);
if (Profile->get_trx()) {
add_routes (ret, false, false, false);
add_routes (ret, false, false, false, PresentationInfo::max_order);
} else {
add_routes (ret, true, true, false);
add_routes (ret, true, true, false, PresentationInfo::max_order);
}
IO::enable_connecting ();
}
@ -3344,11 +3336,11 @@ Session::new_route_from_template (uint32_t how_many, XMLNode& node, const std::s
}
void
Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save)
Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save, PresentationInfo::order_t order)
{
try {
PBD::Unwinder<bool> aip (_adding_routes_in_progress, true);
add_routes_inner (new_routes, input_auto_connect, output_auto_connect);
add_routes_inner (new_routes, input_auto_connect, output_auto_connect, order);
} catch (...) {
error << _("Adding new tracks/busses failed") << endmsg;
@ -3365,25 +3357,18 @@ Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output
save_state (_current_snapshot_name);
}
reassign_track_numbers();
update_route_record_state ();
RouteAdded (new_routes); /* EMIT SIGNAL */
}
void
Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect)
Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, PresentationInfo::order_t order)
{
ChanCount existing_inputs;
ChanCount existing_outputs;
uint32_t order = next_control_id();
if (_order_hint > -1) {
order = _order_hint;
_order_hint = -1;
}
uint32_t n_routes;
uint32_t added = 0;
count_existing_track_channels (existing_inputs, existing_outputs);
@ -3391,6 +3376,7 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
RCUWriter<RouteList> writer (routes);
boost::shared_ptr<RouteList> r = writer.get_copy ();
r->insert (r->end(), new_routes.begin(), new_routes.end());
n_routes = r->size();
/* if there is no control out and we're not in the middle of loading,
* resort the graph here. if there is a control out, we will resort
@ -3403,7 +3389,10 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
}
}
for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("ensure order gap starting at %1 for %2\n", order, new_routes.size()));
ensure_presentation_info_gap (order, new_routes.size());
for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x, ++added) {
boost::weak_ptr<Route> wpr (*x);
boost::shared_ptr<Route> r (*x);
@ -3436,28 +3425,41 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
}
}
if (!r->presentation_info().special()) {
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("checking PI state for %1\n", r->name()));
/* presentation info order may already have been set from XML */
if (r->presentation_info().unordered()) {
if (order == PresentationInfo::max_order) {
/* just add to the end */
r->set_presentation_group_order_explicit (n_routes + added);
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order not set, set to NR %1 + %2 = %3\n", n_routes, added, n_routes + added));
} else {
r->set_presentation_group_order_explicit (order + added);
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order not set, set to %1 + %2 = %3\n", order, added, order + added));
}
} else {
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order already set to %1\n", r->presentation_info().group_order()));
}
}
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("added route %1, group order %2 global order %3 type %4 (summary: %5)\n",
r->name(),
r->presentation_info().group_order(),
r->presentation_info().global_order(),
enum_2_string (r->presentation_info().flags()),
r->presentation_info().to_string()));
if (input_auto_connect || output_auto_connect) {
auto_connect_route (r, input_auto_connect, ChanCount (), ChanCount (), existing_inputs, existing_outputs);
existing_inputs += r->n_inputs();
existing_outputs += r->n_outputs();
}
/* order keys are a GUI responsibility but we need to set up
reasonable defaults because they also affect the remote control
ID in most situations.
*/
if (!r->has_order_key ()) {
if (r->is_auditioner()) {
/* use an arbitrarily high value */
r->set_order_key (UINT_MAX);
} else {
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("while adding, set %1 to order key %2\n", r->name(), order));
r->set_order_key (order);
order++;
}
}
ARDOUR::GUIIdle ();
}
@ -3631,7 +3633,6 @@ Session::remove_routes (boost::shared_ptr<RouteList> routes_to_remove)
} // end of RCU Writer scope
update_route_solo_state ();
RouteAddedOrRemoved (false); /* EMIT SIGNAL */
update_latency_compensation ();
set_dirty();
@ -3668,7 +3669,7 @@ Session::remove_routes (boost::shared_ptr<RouteList> routes_to_remove)
return;
}
Route::RemoteControlIDChange(); /* EMIT SIGNAL */
Stripable::PresentationInfoChange(); /* EMIT SIGNAL */
/* save the new state of the world */
@ -3676,7 +3677,6 @@ Session::remove_routes (boost::shared_ptr<RouteList> routes_to_remove)
save_history (_current_snapshot_name);
}
reassign_track_numbers();
update_route_record_state ();
}
@ -4028,7 +4028,7 @@ Session::get_routes_with_internal_returns() const
}
bool
Session::io_name_is_legal (const std::string& name)
Session::io_name_is_legal (const std::string& name) const
{
boost::shared_ptr<RouteList> r = routes.reader ();
@ -4137,7 +4137,7 @@ Session::routes_using_input_from (const string& str, RouteList& rl)
}
boost::shared_ptr<Route>
Session::route_by_name (string name)
Session::route_by_name (string name) const
{
boost::shared_ptr<RouteList> r = routes.reader ();
@ -4151,7 +4151,7 @@ Session::route_by_name (string name)
}
boost::shared_ptr<Route>
Session::route_by_id (PBD::ID id)
Session::route_by_id (PBD::ID id) const
{
boost::shared_ptr<RouteList> r = routes.reader ();
@ -4180,7 +4180,7 @@ Session::processor_by_id (PBD::ID id) const
}
boost::shared_ptr<Track>
Session::track_by_diskstream_id (PBD::ID id)
Session::track_by_diskstream_id (PBD::ID id) const
{
boost::shared_ptr<RouteList> r = routes.reader ();
@ -4195,37 +4195,34 @@ Session::track_by_diskstream_id (PBD::ID id)
}
boost::shared_ptr<Route>
Session::route_by_remote_id (uint32_t id)
Session::get_remote_nth_route (uint16_t n) const
{
boost::shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i)->remote_control_id() == id) {
return *i;
}
}
return boost::shared_ptr<Route> ((Route*) 0);
return boost::dynamic_pointer_cast<Route> (get_remote_nth_stripable (n, PresentationInfo::Route));
}
boost::shared_ptr<Stripable>
Session::stripable_by_remote_id (uint32_t id)
Session::get_remote_nth_stripable (uint16_t n, PresentationInfo::Flag flags) const
{
boost::shared_ptr<RouteList> r = routes.reader ();
vector<boost::shared_ptr<Route> > v;
if (n > r->size()) {
return boost::shared_ptr<Route> ();
}
v.assign (r->size(), boost::shared_ptr<Route>());
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i)->remote_control_id() == id) {
return *i;
if ((*i)->presentation_info().flag_match (flags)) {
v[(*i)->presentation_info().group_order()] = (*i);
}
}
return boost::shared_ptr<Route> ((Route*) 0);
return v[n];
}
boost::shared_ptr<Route>
Session::route_by_selected_count (uint32_t id)
Session::route_by_selected_count (uint32_t id) const
{
boost::shared_ptr<RouteList> r = routes.reader ();
@ -4236,6 +4233,19 @@ Session::route_by_selected_count (uint32_t id)
return boost::shared_ptr<Route> ((Route*) 0);
}
struct PresentationOrderSorter {
bool operator() (boost::shared_ptr<Stripable> a, boost::shared_ptr<Stripable> b) {
if (a->presentation_info().special() && !b->presentation_info().special()) {
/* a is not ordered, b is; b comes before a */
return false;
} else if (b->presentation_info().unordered() && !a->presentation_info().unordered()) {
/* b is not ordered, a is; a comes before b */
return true;
} else {
return a->presentation_info().global_order() < b->presentation_info().global_order();
}
}
};
void
Session::reassign_track_numbers ()
@ -4243,7 +4253,7 @@ Session::reassign_track_numbers ()
int64_t tn = 0;
int64_t bn = 0;
RouteList r (*(routes.reader ()));
SignalOrderRouteSorter sorter;
PresentationOrderSorter sorter;
r.sort (sorter);
StateProtector sp (this);
@ -5319,7 +5329,7 @@ Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::
if (b->is_monitor()) {
return false;
}
return a->order_key () < b->order_key ();
return a->presentation_info() < b->presentation_info();
}
bool
@ -6659,31 +6669,8 @@ Session::session_name_is_legal (const string& path)
return 0;
}
uint32_t
Session::next_control_id () const
{
int subtract = 0;
/* the monitor bus remote ID is in a different
* "namespace" than regular routes. its existence doesn't
* affect normal (low) numbered routes.
*/
if (_monitor_out) {
subtract++;
}
/* the same about masterbus in Waves Tracks */
if (Profile->get_trx() && _master_out) {
subtract++;
}
return nroutes() - subtract;
}
void
Session::notify_remote_id_change ()
Session::notify_presentation_info_change ()
{
if (deletion_in_progress()) {
return;
@ -6691,41 +6678,21 @@ Session::notify_remote_id_change ()
switch (Config->get_remote_model()) {
case MixerOrdered:
Route::RemoteControlIDChange (); /* EMIT SIGNAL */
Stripable::PresentationInfoChange (); /* EMIT SIGNAL */
break;
default:
break;
}
#ifdef USE_TRACKS_CODE_FEATURES
/* Waves Tracks: for Waves Tracks session it's required to reconnect their IOs
* if track order has been changed by user
*/
reconnect_existing_routes(true, true);
#endif
}
void
Session::sync_order_keys ()
{
if (deletion_in_progress()) {
return;
}
/* tell everyone that something has happened to the sort keys
and let them sync up with the change(s)
this will give objects that manage the sort order keys the
opportunity to keep them in sync if they wish to.
*/
DEBUG_TRACE (DEBUG::OrderKeys, "Sync Order Keys.\n");
reassign_track_numbers();
Route::SyncOrderKeys (); /* EMIT SIGNAL */
#ifdef USE_TRACKS_CODE_FEATURES
/* Waves Tracks: for Waves Tracks session it's required to reconnect their IOs
* if track order has been changed by user
*/
reconnect_existing_routes(true, true);
#endif
DEBUG_TRACE (DEBUG::OrderKeys, "\tsync done\n");
}
bool

View File

@ -335,6 +335,30 @@ Session::mmc_shuttle (MIDI::MachineControl &/*mmc*/, float speed, bool forw)
}
}
boost::shared_ptr<Route>
Session::get_midi_nth_route_by_id (PresentationInfo::order_t n) const
{
PresentationInfo id (PresentationInfo::Flag (0));
if (n == 318) {
id.set_flags (PresentationInfo::MasterOut);
} else if (n == 319) {
id.set_flags (PresentationInfo::MonitorOut);
} else {
id = PresentationInfo (n, PresentationInfo::Route);
}
boost::shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i)->presentation_info().match (id)) {
return *i;
}
}
return boost::shared_ptr<Route>();
}
void
Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
{
@ -342,17 +366,13 @@ Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
return;
}
RouteList::iterator i;
boost::shared_ptr<RouteList> r = routes.reader();
boost::shared_ptr<Route> r = get_midi_nth_route_by_id (trk);
for (i = r->begin(); i != r->end(); ++i) {
AudioTrack *at;
if (r) {
boost::shared_ptr<AudioTrack> at;
if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
if (trk == at->remote_control_id()) {
at->rec_enable_control()->set_value (enabled, Controllable::UseGroup);
break;
}
if ((at = boost::dynamic_pointer_cast<AudioTrack> (r))) {
at->rec_enable_control()->set_value (enabled, Controllable::UseGroup);
}
}
}
@ -696,4 +716,3 @@ Session::mtc_input_port () const
{
return _midi_ports->mtc_input_port ();
}

View File

@ -628,7 +628,7 @@ Session::create (const string& session_template, BusProfile* bus_profile)
_state_of_the_state = Clean;
/* set up Master Out and Control Out if necessary */
/* set up Master Out and Monitor Out if necessary */
if (bus_profile) {
@ -637,7 +637,7 @@ Session::create (const string& session_template, BusProfile* bus_profile)
// Waves Tracks: always create master bus for Tracks
if (ARDOUR::Profile->get_trx() || bus_profile->master_out_channels) {
boost::shared_ptr<Route> r (new Route (*this, _("Master"), Route::MasterOut, DataType::AUDIO));
boost::shared_ptr<Route> r (new Route (*this, _("Master"), PresentationInfo::MasterOut, DataType::AUDIO));
if (r->init ()) {
return -1;
}
@ -658,7 +658,7 @@ Session::create (const string& session_template, BusProfile* bus_profile)
}
if (!rl.empty()) {
add_routes (rl, false, false, false);
add_routes (rl, false, false, false, PresentationInfo::max_order);
}
// Waves Tracks: Skip this. Always use autoconnection for Tracks
@ -1593,7 +1593,7 @@ Session::load_routes (const XMLNode& node, int version)
BootMessage (_("Tracks/busses loaded; Adding to Session"));
add_routes (new_routes, false, false, false);
add_routes (new_routes, false, false, false, PresentationInfo::max_order);
BootMessage (_("Finished adding tracks/busses"));
@ -1642,12 +1642,7 @@ Session::XMLRouteFactory (const XMLNode& node, int version)
ret = track;
} else {
enum Route::Flag flags = Route::Flag(0);
XMLProperty const * prop = node.property("flags");
if (prop) {
flags = Route::Flag (string_2_enum (prop->value(), flags));
}
PresentationInfo::Flag flags = PresentationInfo::get_flags (node);
boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
if (r->init () == 0 && r->set_state (node, version) == 0) {
@ -1716,12 +1711,7 @@ Session::XMLRouteFactory_2X (const XMLNode& node, int version)
ret = track;
} else {
enum Route::Flag flags = Route::Flag(0);
XMLProperty const * prop = node.property("flags");
if (prop) {
flags = Route::Flag (string_2_enum (prop->value(), flags));
}
PresentationInfo::Flag flags = PresentationInfo::get_flags (node);
boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
if (r->init () == 0 && r->set_state (node, version) == 0) {
@ -3423,7 +3413,7 @@ Session::controllable_by_descriptor (const ControllableDescriptor& desc)
}
case ControllableDescriptor::RemoteControlID:
r = route_by_remote_id (desc.rid());
r = get_remote_nth_route (desc.rid());
break;
case ControllableDescriptor::SelectionCount:

160
libs/ardour/stripable.cc Normal file
View File

@ -0,0 +1,160 @@
/*
Copyright (C) 2016 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <boost/algorithm/string.hpp>
#include "pbd/compose.h"
#include "pbd/convert.h"
#include "ardour/debug.h"
#include "ardour/rc_configuration.h"
#include "ardour/stripable.h"
#include "i18n.h"
using namespace ARDOUR;
using namespace PBD;
using std::string;
PBD::Signal0<void> Stripable::PresentationInfoChange;
Stripable::Stripable (Session& s, string const & name, PresentationInfo const & pi)
: SessionObject (s, name)
, _presentation_info (pi)
{
}
void
Stripable::set_presentation_group_order (PresentationInfo::order_t order, bool notify_class_listeners)
{
set_presentation_info_internal (PresentationInfo (order, _presentation_info.flags()), notify_class_listeners);
}
void
Stripable::set_presentation_group_order_explicit (PresentationInfo::order_t order)
{
set_presentation_group_order (order, false);
}
void
Stripable::set_presentation_info (PresentationInfo pi, bool notify_class_listeners)
{
if (Config->get_remote_model() != UserOrdered) {
return;
}
set_presentation_info_internal (pi, notify_class_listeners);
}
void
Stripable::set_presentation_info_internal (PresentationInfo pi, bool notify_class_listeners)
{
if (pi != presentation_info()) {
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1: set edit-based RID to %2\n", name(), pi));
if (is_master()) {
_presentation_info = PresentationInfo (0, PresentationInfo::MasterOut);
} else if (is_monitor()) {
_presentation_info = PresentationInfo (0, PresentationInfo::MonitorOut);
} else {
_presentation_info = pi;
}
PresentationInfoChanged ();
if (notify_class_listeners) {
PresentationInfoChange ();
}
}
}
void
Stripable::set_presentation_info_explicit (PresentationInfo pi)
{
set_presentation_info_internal (pi, false);
}
int
Stripable::set_state (XMLNode const& node, int version)
{
const XMLProperty *prop;
XMLNodeList const & nlist (node.children());
XMLNodeConstIterator niter;
XMLNode *child;
if (version > 3000) {
std::cerr << "Looking for PI\n";
for (niter = nlist.begin(); niter != nlist.end(); ++niter){
child = *niter;
if (child->name() == X_("PresentationInfo")) {
std::cerr << "Found it\n";
if ((prop = child->property (X_("value"))) != 0) {
_presentation_info = prop->value ();
std::cerr << "Set pinfo to " << _presentation_info << " from " << prop->value() << std::endl;
}
}
}
} else {
std::cerr << "Old\n";
/* Older versions of Ardour stored "_flags" as a property of the Route
* node, only for 3 special Routes (MasterOut, MonitorOut, Auditioner.
*
* Their presentation order was stored in a node called "RemoteControl"
*
* This information is now part of the PresentationInfo of every Stripable.
*/
if ((prop = node.property (X_("flags"))) != 0) {
/* 4.x and earlier - didn't have Stripable but the
* relevant enums have the same names (MasterOut,
* MonitorOut, Auditioner), so we can use string_2_enum
*/
PresentationInfo::Flag flags;
if (version < 3000) {
string f (prop->value());
boost::replace_all (f, "ControlOut", "MonitorOut");
flags = PresentationInfo::Flag (string_2_enum (f, flags));
} else {
flags = PresentationInfo::Flag (string_2_enum (prop->value(), flags));
}
_presentation_info.set_flags (flags);
}
}
return 0;
}
void
Stripable::add_state (XMLNode& node) const
{
XMLNode* remote_control_node = new XMLNode (X_("PresentationInfo"));
remote_control_node->add_property (X_("value"), _presentation_info.to_string());
node.add_child_nocopy (*remote_control_node);
}

View File

@ -40,7 +40,7 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, DataType default_type)
Track::Track (Session& sess, string name, PresentationInfo::Flag flag, TrackMode mode, DataType default_type)
: Route (sess, name, flag, default_type)
, _saved_meter_point (_meter_point)
, _mode (mode)
@ -75,7 +75,6 @@ Track::init ()
_monitoring_control.reset (new MonitorControl (_session, X_("monitoring"), *this));
add_control (_monitoring_control);
track_number_changed.connect_same_thread (*this, boost::bind (&Track::resync_track_name, this));
_session.config.ParameterChanged.connect_same_thread (*this, boost::bind (&Track::parameter_changed, this, _1));
_monitoring_control->Changed.connect_same_thread (*this, boost::bind (&Track::monitoring_changed, this, _1, _2));

View File

@ -65,7 +65,7 @@ VCA::get_next_vca_number ()
}
VCA::VCA (Session& s, uint32_t num, const string& name)
: Stripable (s, name)
: Stripable (s, name, PresentationInfo (num, PresentationInfo::VCA))
, Muteable (s, name)
, Automatable (s)
, _number (num)
@ -106,6 +106,8 @@ VCA::get_state ()
node->add_property (X_("name"), _name);
node->add_property (X_("number"), _number);
Stripable::add_state (*node);
node->add_child_nocopy (_gain_control->get_state());
node->add_child_nocopy (_solo_control->get_state());
node->add_child_nocopy (_mute_control->get_state());
@ -121,6 +123,8 @@ VCA::set_state (XMLNode const& node, int version)
{
XMLProperty const* prop;
Stripable::set_state (node, version);
if ((prop = node.property ("name")) != 0) {
set_name (prop->value());
}

View File

@ -169,6 +169,7 @@ libardour_sources = [
'port_insert.cc',
'port_manager.cc',
'port_set.cc',
'presentation_info.cc',
'process_thread.cc',
'processor.cc',
'progress.cc',
@ -225,6 +226,7 @@ libardour_sources = [
'source_factory.cc',
'speakers.cc',
'srcfilesource.cc',
'stripable.cc',
'strip_silence.cc',
'system_exec.cc',
'revision.cc',

View File

@ -46,10 +46,10 @@ PBD::Signal0<void> ControlProtocol::VerticalZoomOutAll;
PBD::Signal0<void> ControlProtocol::VerticalZoomInSelected;
PBD::Signal0<void> ControlProtocol::VerticalZoomOutSelected;
PBD::Signal1<void,RouteNotificationListPtr> ControlProtocol::TrackSelectionChanged;
PBD::Signal1<void,uint32_t> ControlProtocol::AddRouteToSelection;
PBD::Signal1<void,uint32_t> ControlProtocol::SetRouteSelection;
PBD::Signal1<void,uint32_t> ControlProtocol::ToggleRouteSelection;
PBD::Signal1<void,uint32_t> ControlProtocol::RemoveRouteFromSelection;
PBD::Signal1<void,uint64_t> ControlProtocol::AddRouteToSelection;
PBD::Signal1<void,uint64_t> ControlProtocol::SetRouteSelection;
PBD::Signal1<void,uint64_t> ControlProtocol::ToggleRouteSelection;
PBD::Signal1<void,uint64_t> ControlProtocol::RemoveRouteFromSelection;
PBD::Signal0<void> ControlProtocol::ClearRouteSelection;
PBD::Signal0<void> ControlProtocol::StepTracksDown;
PBD::Signal0<void> ControlProtocol::StepTracksUp;
@ -77,82 +77,18 @@ ControlProtocol::set_active (bool yn)
void
ControlProtocol::next_track (uint32_t initial_id)
{
uint32_t limit = session->nroutes();
boost::shared_ptr<Route> cr = route_table[0];
uint32_t id;
if (cr) {
id = cr->remote_control_id ();
} else {
id = 0;
}
if (id == limit) {
id = 0;
} else {
id++;
}
while (id <= limit) {
if ((cr = session->route_by_remote_id (id)) != 0) {
break;
}
id++;
}
if (id >= limit) {
id = 0;
while (id != initial_id) {
if ((cr = session->route_by_remote_id (id)) != 0) {
break;
}
id++;
}
}
route_table[0] = cr;
// STRIPABLE route_table[0] = _session->get_nth_stripable (++initial_id, RemoteControlID::Route);
}
void
ControlProtocol::prev_track (uint32_t initial_id)
{
uint32_t limit = session->nroutes();
boost::shared_ptr<Route> cr = route_table[0];
int32_t id;
if (cr) {
id = cr->remote_control_id ();
} else {
id = 0;
if (!initial_id) {
return;
}
if (id == 0) {
id = limit;
} else {
id--;
}
while (id >= 0) {
if ((cr = session->route_by_remote_id (id)) != 0) {
break;
}
id--;
}
if (id < 0) {
uint32_t i = limit;
while (i > initial_id) {
if ((cr = session->route_by_remote_id (i)) != 0) {
break;
}
i--;
}
}
route_table[0] = cr;
// STRIPABLE route_table[0] = _session->get_nth_stripable (--initial_id, RemoteControlID::Route);
}
void
ControlProtocol::set_route_table_size (uint32_t size)
{
@ -176,6 +112,7 @@ ControlProtocol::set_route_table (uint32_t table_index, boost::shared_ptr<ARDOUR
bool
ControlProtocol::set_route_table (uint32_t table_index, uint32_t remote_control_id)
{
#if 0 // STRIPABLE
boost::shared_ptr<Route> r = session->route_by_remote_id (remote_control_id);
if (!r) {
@ -183,7 +120,7 @@ ControlProtocol::set_route_table (uint32_t table_index, uint32_t remote_control_
}
set_route_table (table_index, r);
#endif
return true;
}

View File

@ -78,10 +78,10 @@ class LIBCONTROLCP_API ControlProtocol : public PBD::Stateful, public PBD::Scope
static PBD::Signal0<void> StepTracksDown;
static PBD::Signal0<void> StepTracksUp;
static PBD::Signal1<void,uint32_t> AddRouteToSelection;
static PBD::Signal1<void,uint32_t> SetRouteSelection;
static PBD::Signal1<void,uint32_t> ToggleRouteSelection;
static PBD::Signal1<void,uint32_t> RemoveRouteFromSelection;
static PBD::Signal1<void,uint64_t> AddRouteToSelection;
static PBD::Signal1<void,uint64_t> SetRouteSelection;
static PBD::Signal1<void,uint64_t> ToggleRouteSelection;
static PBD::Signal1<void,uint64_t> RemoveRouteFromSelection;
static PBD::Signal0<void> ClearRouteSelection;
/* signals that one UI (e.g. the GUI) can emit to get all other UI's to

View File

@ -95,7 +95,7 @@ GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
/* this one is cross-thread */
Route::RemoteControlIDChange.connect (*this, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::reset_controllables, this), midi_ui_context());
Stripable::PresentationInfoChange.connect (*this, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::reset_controllables, this), midi_ui_context());
/* Catch port connections and disconnections (cross-thread) */
ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR,

View File

@ -242,21 +242,21 @@ MackieControlProtocol::route_is_locked_to_strip (boost::shared_ptr<Route> r) con
}
// predicate for sort call in get_sorted_routes
struct RouteByRemoteId
struct RouteByPresentationOrder
{
bool operator () (const boost::shared_ptr<Route> & a, const boost::shared_ptr<Route> & b) const
{
return a->remote_control_id() < b->remote_control_id();
return a->presentation_info() < b->presentation_info();
}
bool operator () (const Route & a, const Route & b) const
{
return a.remote_control_id() < b.remote_control_id();
return a.presentation_info() < b.presentation_info();
}
bool operator () (const Route * a, const Route * b) const
{
return a->remote_control_id() < b->remote_control_id();
return a->presentation_info() < b->presentation_info();
}
};
@ -267,30 +267,22 @@ MackieControlProtocol::get_sorted_routes()
// fetch all routes
boost::shared_ptr<RouteList> routes = session->get_routes();
set<uint32_t> remote_ids;
set<PresentationInfo> remote_ids;
// routes with remote_id 0 should never be added
// TODO verify this with ardour devs
// remote_ids.insert (0);
// sort in remote_id order, and exclude master, control and hidden routes
// sort in presentation order, and exclude master, control and hidden routes
// and any routes that are already set.
for (RouteList::iterator it = routes->begin(); it != routes->end(); ++it) {
boost::shared_ptr<Route> route = *it;
if (remote_ids.find (route->remote_control_id()) != remote_ids.end()) {
continue;
}
if (route->is_auditioner() || route->is_master() || route->is_monitor()) {
continue;
}
/* don't include locked routes */
if (route_is_locked_to_strip(route)) {
if (route_is_locked_to_strip (route)) {
continue;
}
@ -298,13 +290,13 @@ MackieControlProtocol::get_sorted_routes()
case Mixer:
if (! is_hidden(route)) {
sorted.push_back (route);
remote_ids.insert (route->remote_control_id());
remote_ids.insert (route->presentation_info());
}
break;
case AudioTracks:
if (is_audio_track(route) && !is_hidden(route)) {
sorted.push_back (route);
remote_ids.insert (route->remote_control_id());
remote_ids.insert (route->presentation_info());
}
break;
case Busses:
@ -312,20 +304,20 @@ MackieControlProtocol::get_sorted_routes()
#ifdef MIXBUS
if (route->mixbus()) {
sorted.push_back (route);
remote_ids.insert (route->remote_control_id());
remote_ids.insert (route->presentation_info());
}
#endif
} else {
if (!is_track(route) && !is_hidden(route)) {
sorted.push_back (route);
remote_ids.insert (route->remote_control_id());
remote_ids.insert (route->presentation_info());
}
}
break;
case MidiTracks:
if (is_midi_track(route) && !is_hidden(route)) {
sorted.push_back (route);
remote_ids.insert (route->remote_control_id());
remote_ids.insert (route->presentation_info());
}
break;
case Plugins:
@ -338,27 +330,27 @@ MackieControlProtocol::get_sorted_routes()
#endif
{
sorted.push_back (route);
remote_ids.insert (route->remote_control_id());
remote_ids.insert (route->presentation_info());
}
break;
case Hidden: // Show all the tracks we have hidden
if (is_hidden(route)) {
// maybe separate groups
sorted.push_back (route);
remote_ids.insert (route->remote_control_id());
remote_ids.insert (route->presentation_info());
}
break;
case Selected: // For example: a group (this is USER)
if (selected(route) && !is_hidden(route)) {
sorted.push_back (route);
remote_ids.insert (route->remote_control_id());
remote_ids.insert (route->presentation_info());
}
break;
}
}
sort (sorted.begin(), sorted.end(), RouteByRemoteId());
sort (sorted.begin(), sorted.end(), RouteByPresentationOrder());
return sorted;
}
@ -716,7 +708,6 @@ MackieControlProtocol::connect_session_signals()
{
// receive routes added
session->RouteAdded.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_route_added, this, _1), this);
session->RouteAddedOrRemoved.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_route_added_or_removed, this), this);
// receive record state toggled
session->RecordStateChanged.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_record_state_changed, this), this);
// receive transport state changed
@ -733,7 +724,7 @@ MackieControlProtocol::connect_session_signals()
Sorted sorted = get_sorted_routes();
for (Sorted::iterator it = sorted.begin(); it != sorted.end(); ++it) {
(*it)->RemoteControlIDChanged.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_remote_id_changed, this), this);
(*it)->PresentationInfoChanged.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_presentation_info_changed, this), this);
}
}
@ -1251,7 +1242,7 @@ void MackieControlProtocol::notify_parameter_changed (std::string const & p)
}
void
MackieControlProtocol::notify_route_added_or_removed ()
MackieControlProtocol::notify_route_removed ()
{
Glib::Threads::Mutex::Lock lm (surfaces_lock);
for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
@ -1291,7 +1282,7 @@ MackieControlProtocol::notify_route_added (ARDOUR::RouteList & rl)
typedef ARDOUR::RouteList ARS;
for (ARS::iterator it = rl.begin(); it != rl.end(); ++it) {
(*it)->RemoteControlIDChanged.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_remote_id_changed, this), this);
(*it)->PresentationInfoChanged.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_presentation_info_changed, this), this);
}
}
@ -1320,7 +1311,7 @@ MackieControlProtocol::notify_solo_active_changed (bool active)
}
void
MackieControlProtocol::notify_remote_id_changed()
MackieControlProtocol::notify_presentation_info_changed()
{
{
Glib::Threads::Mutex::Lock lm (surfaces_lock);
@ -2120,12 +2111,15 @@ MackieControlProtocol::select_range ()
for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
if (main_modifier_state() == MODIFIER_SHIFT) {
ToggleRouteSelection ((*r)->remote_control_id ());
/* XXX can only use numeric part of ID at present */
ToggleRouteSelection ((*r)->presentation_info ().global_order());
} else {
if (r == routes.begin()) {
SetRouteSelection ((*r)->remote_control_id());
/* XXX can only use numeric part of ID at present */
SetRouteSelection ((*r)->presentation_info().global_order());
} else {
AddRouteToSelection ((*r)->remote_control_id());
/* XXX can only use numeric part of ID at present */
AddRouteToSelection ((*r)->presentation_info().global_order());
}
}
}
@ -2441,7 +2435,7 @@ MackieControlProtocol::is_hidden (boost::shared_ptr<Route> r) const
if (!r) {
return false;
}
return (((r->remote_control_id()) >>31) != 0);
return (r->presentation_info().flags() & PresentationInfo::Hidden);
}
bool

View File

@ -206,9 +206,9 @@ class MackieControlProtocol
void handle_button_event (Mackie::Surface&, Mackie::Button& button, Mackie::ButtonState);
void notify_subview_route_deleted ();
void notify_route_added_or_removed ();
void notify_route_removed ();
void notify_route_added (ARDOUR::RouteList &);
void notify_remote_id_changed();
void notify_presentation_info_changed();
void recalibrate_faders ();
void toggle_backlight ();

View File

@ -321,6 +321,7 @@ Strip::notify_active_changed ()
void
Strip::notify_route_deleted ()
{
_surface->mcp().notify_route_removed ();
_surface->mcp().refresh_current_bank();
}

View File

@ -658,7 +658,7 @@ OSC::send_current_value (const char* path, lo_arg** argv, int argc, lo_message m
lo_message_add_string (reply, "bad syntax");
} else {
id = argv[0]->i;
r = session->route_by_remote_id (id);
r = session->get_remote_nth_route (id);
if (!r) {
lo_message_add_string (reply, "not found");
@ -729,7 +729,7 @@ OSC::catchall (const char *path, const char* types, lo_arg **argv, int argc, lo_
} else {
for (int n = 0; n < argc; ++n) {
boost::shared_ptr<Route> r = session->route_by_remote_id (argv[n]->i);
boost::shared_ptr<Route> r = session->get_remote_nth_route (argv[n]->i);
if (!r) {
lo_message_add_string (reply, "not found");
@ -752,7 +752,7 @@ OSC::catchall (const char *path, const char* types, lo_arg **argv, int argc, lo_
for (int n = 0; n < argc; ++n) {
boost::shared_ptr<Route> r = session->route_by_remote_id (argv[n]->i);
boost::shared_ptr<Route> r = session->get_remote_nth_route (argv[n]->i);
if (r) {
end_listen (r, lo_message_get_source (msg));
@ -949,7 +949,7 @@ OSC::routes_list (lo_message msg)
}
for (int n = 0; n < (int) session->nroutes(); ++n) {
boost::shared_ptr<Route> r = session->route_by_remote_id (n);
boost::shared_ptr<Route> r = session->get_remote_nth_route (n);
if (r) {
@ -968,7 +968,8 @@ OSC::routes_list (lo_message msg)
lo_message_add_int32 (reply, r->n_outputs().n_audio());
lo_message_add_int32 (reply, r->muted());
lo_message_add_int32 (reply, r->soloed());
lo_message_add_int32 (reply, r->remote_control_id());
/* XXX Can only use group ID at this point */
lo_message_add_int32 (reply, r->presentation_info().group_order());
if (boost::dynamic_pointer_cast<AudioTrack>(r)
|| boost::dynamic_pointer_cast<MidiTrack>(r)) {
@ -1051,7 +1052,7 @@ OSC::route_mute (int rid, int yn)
{
if (!session) return -1;
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
if (r) {
r->mute_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
@ -1065,7 +1066,7 @@ OSC::route_solo (int rid, int yn)
{
if (!session) return -1;
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
if (r) {
r->solo_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
@ -1079,7 +1080,7 @@ OSC::route_recenable (int rid, int yn)
{
if (!session) return -1;
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
if (r) {
boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<Track> (r);
@ -1096,7 +1097,7 @@ OSC::route_set_gain_abs (int rid, float level)
{
if (!session) return -1;
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
if (r) {
r->gain_control()->set_value (level, PBD::Controllable::NoGroup);
@ -1126,7 +1127,7 @@ OSC::route_set_trim_abs (int rid, float level)
{
if (!session) return -1;
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
if (r) {
r->set_trim (level, PBD::Controllable::NoGroup);
@ -1147,7 +1148,7 @@ OSC::route_set_pan_stereo_position (int rid, float pos)
{
if (!session) return -1;
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
if (r) {
boost::shared_ptr<Panner> panner = r->panner();
@ -1165,7 +1166,7 @@ OSC::route_set_pan_stereo_width (int rid, float pos)
{
if (!session) return -1;
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
if (r) {
boost::shared_ptr<Panner> panner = r->panner();
@ -1185,7 +1186,7 @@ OSC::route_set_send_gain_abs (int rid, int sid, float val)
return -1;
}
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
if (!r) {
return -1;
@ -1217,7 +1218,7 @@ OSC::route_set_send_gain_dB (int rid, int sid, float val)
return -1;
}
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
if (!r) {
return -1;
@ -1248,7 +1249,7 @@ OSC::route_plugin_parameter (int rid, int piid, int par, float val)
if (!session)
return -1;
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
if (!r) {
PBD::error << "OSC: Invalid Remote Control ID '" << rid << "'" << endmsg;
@ -1307,7 +1308,7 @@ OSC::route_plugin_parameter_print (int rid, int piid, int par)
return -1;
}
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
if (!r) {
return -1;

View File

@ -90,7 +90,9 @@ OSCRouteControllable::send_change_message ()
{
lo_message msg = lo_message_new ();
lo_message_add_int32 (msg, _route->remote_control_id());
/* Can only send ID part of RID at present */
lo_message_add_int32 (msg, _route->presentation_info().group_order());
lo_message_add_float (msg, (float) controllable->get_value());
/* XXX thread issues */

View File

@ -82,7 +82,8 @@ OSCRouteObserver::name_changed (const PBD::PropertyChange& what_changed)
lo_message msg = lo_message_new ();
lo_message_add_int32 (msg, _route->remote_control_id());
/* XXX can only use group part of ID at present */
lo_message_add_int32 (msg, _route->presentation_info().group_order());
lo_message_add_string (msg, _route->name().c_str());
lo_send_message (addr, "/route/name", msg);
@ -94,7 +95,8 @@ OSCRouteObserver::send_change_message (string path, boost::shared_ptr<Controllab
{
lo_message msg = lo_message_new ();
lo_message_add_int32 (msg, _route->remote_control_id());
/* XXX can only use group part of ID at present */
lo_message_add_int32 (msg, _route->presentation_info().group_order());
lo_message_add_float (msg, (float) controllable->get_value());
/* XXX thread issues */