first vaguely working version using PresentationInfo
remote control ID and "order keys" have been removed.
This commit is contained in:
parent
bae9474e9f
commit
e0ff70cf86
|
@ -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);
|
||||
|
|
|
@ -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&);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -192,8 +192,3 @@ EditorGroupTabs::selected_routes () const
|
|||
return rl;
|
||||
}
|
||||
|
||||
void
|
||||
EditorGroupTabs::sync_order_keys ()
|
||||
{
|
||||
_editor->_routes->sync_order_keys_from_treeview ();
|
||||
}
|
||||
|
|
|
@ -37,5 +37,4 @@ private:
|
|||
}
|
||||
void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *);
|
||||
ARDOUR::RouteList selected_routes () const;
|
||||
void sync_order_keys ();
|
||||
};
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 &);
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -193,8 +193,3 @@ MixerGroupTabs::selected_routes () const
|
|||
return rl;
|
||||
}
|
||||
|
||||
void
|
||||
MixerGroupTabs::sync_order_keys ()
|
||||
{
|
||||
_mixer->sync_order_keys_from_treeview ();
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@ private:
|
|||
}
|
||||
|
||||
ARDOUR::RouteList selected_routes () const;
|
||||
void sync_order_keys ();
|
||||
|
||||
Mixer_UI* _mixer;
|
||||
};
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 ());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ();
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "ardour/slavable_automation_control.h"
|
||||
|
||||
#include "ardour/mute_master.h"
|
||||
#include "ardour/libardour_visibility.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
|
303
libs/ardour/ardour/presentation_info.h
Normal file
303
libs/ardour/ardour/presentation_info.h
Normal 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__ */
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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__ */
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
121
libs/ardour/presentation_info.cc
Normal file
121
libs/ardour/presentation_info.cc
Normal 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 ();
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
160
libs/ardour/stripable.cc
Normal 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);
|
||||
}
|
|
@ -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));
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -321,6 +321,7 @@ Strip::notify_active_changed ()
|
|||
void
|
||||
Strip::notify_route_deleted ()
|
||||
{
|
||||
_surface->mcp().notify_route_removed ();
|
||||
_surface->mcp().refresh_current_bank();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue
Block a user