From 19e97d1d64e8aa6d87d79d1f6332065992e5e027 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 8 Nov 2011 02:10:56 +0000 Subject: Attempt to fix some confusions caused by bundles containing different types of port; if we loop over N MIDI channels of a mixed bundle, for example, we must convert 0...N to the indices of the channels within the bundle. Also remove the hack of creating new bundles to contain a subset of another bundle's ports; if you do this, any signals emitted by the other bundle are ignored. Should fix #4454. git-svn-id: svn://localhost/ardour2/branches/3.0@10490 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/port_group.cc | 51 +++++--------------------------- gtk2_ardour/port_group.h | 1 - gtk2_ardour/port_matrix_column_labels.cc | 14 ++++++--- gtk2_ardour/port_matrix_component.cc | 2 +- gtk2_ardour/port_matrix_grid.cc | 20 +++++++------ gtk2_ardour/port_matrix_row_labels.cc | 10 +++++-- libs/ardour/ardour/bundle.h | 1 + libs/ardour/bundle.cc | 41 +++++++++++++++++++++++++ 8 files changed, 79 insertions(+), 61 deletions(-) diff --git a/gtk2_ardour/port_group.cc b/gtk2_ardour/port_group.cc index 8383d803a3..a3a7ca8e77 100644 --- a/gtk2_ardour/port_group.cc +++ b/gtk2_ardour/port_group.cc @@ -388,11 +388,10 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp } for (list >::iterator j = i->ios.begin(); j != i->ios.end(); ++j) { - boost::shared_ptr b = bundle_for_type ((*j)->bundle(), type); if (tv) { - g->add_bundle (b, *j, tv->color ()); + g->add_bundle ((*j)->bundle(), *j, tv->color ()); } else { - g->add_bundle (b, *j); + g->add_bundle ((*j)->bundle(), *j); } } } @@ -405,26 +404,21 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp for (BundleList::iterator i = b->begin(); i != b->end(); ++i) { if (boost::dynamic_pointer_cast (*i) && (*i)->ports_are_inputs() == inputs) { - boost::shared_ptr b = bundle_for_type (*i, type); - system->add_bundle (b, allow_dups); + system->add_bundle (*i, allow_dups); } } for (BundleList::iterator i = b->begin(); i != b->end(); ++i) { if (boost::dynamic_pointer_cast (*i) == 0 && (*i)->ports_are_inputs() == inputs) { - boost::shared_ptr b = bundle_for_type (*i, type); - system->add_bundle (b, allow_dups); + system->add_bundle (*i, allow_dups); } } /* Ardour stuff */ if (!inputs) { - boost::shared_ptr b = bundle_for_type (session->the_auditioner()->output()->bundle(), type); - ardour->add_bundle (b); - - b = bundle_for_type (session->click_io()->bundle(), type); - ardour->add_bundle (b); + ardour->add_bundle (session->the_auditioner()->output()->bundle()); + ardour->add_bundle (session->click_io()->bundle()); } /* Ardour's surfaces */ @@ -559,16 +553,14 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp for (DataType::iterator i = DataType::begin(); i != DataType::end(); ++i) { if (!extra_system[*i].empty()) { boost::shared_ptr b = make_bundle_from_ports (extra_system[*i], *i, inputs); - boost::shared_ptr bt = bundle_for_type (b, type); - system->add_bundle (bt); + system->add_bundle (b); } } for (DataType::iterator i = DataType::begin(); i != DataType::end(); ++i) { if (!extra_other[*i].empty()) { boost::shared_ptr b = make_bundle_from_ports (extra_other[*i], *i, inputs); - boost::shared_ptr bt = bundle_for_type (b, type); - other->add_bundle (bt); + other->add_bundle (b); } } @@ -780,30 +772,3 @@ PortGroupList::empty () const return _groups.empty (); } -/** Take a bundle, and either return it, if it contains only ports of type \a t, - * or return a new bundle with those ports from \a b which are of type \a t. - * Note that t == NIL is taken to mean "all types". - */ -boost::shared_ptr -PortGroupList::bundle_for_type (boost::shared_ptr b, DataType t) const -{ - /* We are asked for a bundle with all types, so that's easy */ - if (t == DataType::NIL) { - return b; - } - - if (b->nchannels().get(t) == b->nchannels().n_total()) { - /* All channels on b are of the correct type, so just return b */ - return b; - } - - /* We must build a new bundle */ - boost::shared_ptr n (new ARDOUR::Bundle (b->name(), b->ports_are_inputs())); - for (uint32_t i = 0; i < b->nchannels().n_total(); ++i) { - if (b->channel_type(i) == t) { - n->add_channel (b->channel_name (i), t, b->channel_ports (i)); - } - } - - return n; -} diff --git a/gtk2_ardour/port_group.h b/gtk2_ardour/port_group.h index 1deff38432..3e13c3a5e3 100644 --- a/gtk2_ardour/port_group.h +++ b/gtk2_ardour/port_group.h @@ -146,7 +146,6 @@ class PortGroupList : public sigc::trackable void maybe_add_processor_to_list ( boost::weak_ptr, std::list > *, bool, std::set > & ); - boost::shared_ptr bundle_for_type (boost::shared_ptr, ARDOUR::DataType) const; mutable PortGroup::BundleList _bundles; List _groups; diff --git a/gtk2_ardour/port_matrix_column_labels.cc b/gtk2_ardour/port_matrix_column_labels.cc index 1cdf510c59..99dc369f0a 100644 --- a/gtk2_ardour/port_matrix_column_labels.cc +++ b/gtk2_ardour/port_matrix_column_labels.cc @@ -156,7 +156,11 @@ PortMatrixColumnLabels::render (cairo_t* cr) for (uint32_t j = 0; j < C; ++j) { Gdk::Color c = (*i)->has_colour ? (*i)->colour : get_a_bundle_colour (N); - render_channel_name (cr, background_colour (), c, x, 0, ARDOUR::BundleChannel ((*i)->bundle, j)); + ARDOUR::BundleChannel bc ( + (*i)->bundle, + (*i)->bundle->type_channel_to_overall (_matrix->type (), j) + ); + render_channel_name (cr, background_colour (), c, x, 0, bc); x += grid_spacing(); } @@ -487,9 +491,11 @@ PortMatrixColumnLabels::motion (double x, double y) list n; - uint32_t const N = _matrix->count_of_our_type (w.bundle->nchannels ()); - - for (uint32_t i = 0; i < N; ++i) { + for (uint32_t i = 0; i < w.bundle->nchannels().n_total(); ++i) { + if (!_matrix->should_show (w.bundle->channel_type (i))) { + continue; + } + ARDOUR::BundleChannel const bc (w.bundle, i); n.push_back (PortMatrixNode (ARDOUR::BundleChannel (), bc)); } diff --git a/gtk2_ardour/port_matrix_component.cc b/gtk2_ardour/port_matrix_component.cc index 166488bef0..2637a26d22 100644 --- a/gtk2_ardour/port_matrix_component.cc +++ b/gtk2_ardour/port_matrix_component.cc @@ -197,7 +197,7 @@ PortMatrixComponent::position_to_channel (double p, double, boost::shared_ptrcount_of_our_type_min_1 ((*j)->bundle->nchannels()); if (p < s) { - return ARDOUR::BundleChannel ((*j)->bundle, p); + return ARDOUR::BundleChannel ((*j)->bundle, (*j)->bundle->type_channel_to_overall (_matrix->type (), p)); } else { p -= s; } diff --git a/gtk2_ardour/port_matrix_grid.cc b/gtk2_ardour/port_matrix_grid.cc index 67fa73c097..a4ca3df1b8 100644 --- a/gtk2_ardour/port_matrix_grid.cc +++ b/gtk2_ardour/port_matrix_grid.cc @@ -191,8 +191,16 @@ PortMatrixGrid::render (cairo_t* cr) for (uint32_t l = 0; l < _matrix->count_of_our_type ((*j)->bundle->nchannels()); ++l) { ARDOUR::BundleChannel c[2]; - c[_matrix->column_index()] = ARDOUR::BundleChannel ((*i)->bundle, k); - c[_matrix->row_index()] = ARDOUR::BundleChannel ((*j)->bundle, l); + + c[_matrix->column_index()] = ARDOUR::BundleChannel ( + (*i)->bundle, + (*i)->bundle->type_channel_to_overall (_matrix->type (), k) + ); + + c[_matrix->row_index()] = ARDOUR::BundleChannel ( + (*j)->bundle, + (*j)->bundle->type_channel_to_overall (_matrix->type (), l) + ); if (c[0].bundle->channel_type (c[0].channel) != c[1].bundle->channel_type (c[1].channel)) { /* these two channels are of different types */ @@ -328,13 +336,6 @@ PortMatrixGrid::button_press (double x, double y, int b, uint32_t t, guint) void PortMatrixGrid::set_association (PortMatrixNode node, bool s) { - if (node.row.bundle->nchannels().n_total() == 0 || node.column.bundle->nchannels().n_total() == 0) { - /* One of the bundles has no channels, which means that it has none of the appropriate type, - and is only being displayed to look pretty. So we don't need to do anything. - */ - return; - } - if (_matrix->show_only_bundles()) { for (uint32_t i = 0; i < node.column.bundle->nchannels().n_total(); ++i) { @@ -358,6 +359,7 @@ PortMatrixGrid::set_association (PortMatrixNode node, bool s) ARDOUR::BundleChannel c[2]; c[_matrix->row_index()] = node.row; c[_matrix->column_index()] = node.column; + _matrix->set_state (c, s); } } diff --git a/gtk2_ardour/port_matrix_row_labels.cc b/gtk2_ardour/port_matrix_row_labels.cc index fcfeef13d0..38b2dde6a7 100644 --- a/gtk2_ardour/port_matrix_row_labels.cc +++ b/gtk2_ardour/port_matrix_row_labels.cc @@ -117,7 +117,12 @@ PortMatrixRowLabels::render (cairo_t* cr) uint32_t const N = _matrix->count_of_our_type ((*i)->bundle->nchannels()); for (uint32_t j = 0; j < N; ++j) { Gdk::Color c = (*i)->has_colour ? (*i)->colour : get_a_bundle_colour (M); - render_channel_name (cr, background_colour (), c, 0, y, ARDOUR::BundleChannel ((*i)->bundle, j)); + ARDOUR::BundleChannel bc ( + (*i)->bundle, + (*i)->bundle->type_channel_to_overall (_matrix->type (), j) + ); + + render_channel_name (cr, background_colour (), c, 0, y, bc); y += grid_spacing(); ++M; } @@ -334,8 +339,7 @@ PortMatrixRowLabels::motion (double x, double y) list n; for (uint32_t i = 0; i < w.bundle->nchannels().n_total(); ++i) { - - if (!_matrix->should_show (w.bundle->channel_type(i))) { + if (!_matrix->should_show (w.bundle->channel_type (i))) { continue; } diff --git a/libs/ardour/ardour/bundle.h b/libs/ardour/ardour/bundle.h index 6b8586a46a..821dd57896 100644 --- a/libs/ardour/ardour/bundle.h +++ b/libs/ardour/ardour/bundle.h @@ -100,6 +100,7 @@ class Bundle : public PBD::ScopedConnectionList void disconnect (boost::shared_ptr, AudioEngine &); bool connected_to (boost::shared_ptr, AudioEngine &); bool has_same_ports (boost::shared_ptr) const; + uint32_t type_channel_to_overall (DataType, uint32_t) const; void set_name (std::string const &); diff --git a/libs/ardour/bundle.cc b/libs/ardour/bundle.cc index d8666c5bbb..d9fc86e2ad 100644 --- a/libs/ardour/bundle.cc +++ b/libs/ardour/bundle.cc @@ -517,3 +517,44 @@ Bundle::operator== (Bundle const & other) { return _channel == other._channel; } + +/** Given an index of a channel as the nth channel of a particular type, + * return an index of that channel when considering channels of all types. + * + * e.g. given a bundle with channels: + * fred [audio] + * jim [audio] + * sheila [midi] + * + * If t == MIDI and c == 0, then we would return 2, as 2 is the index of the + * 0th MIDI channel. + */ + +uint32_t +Bundle::type_channel_to_overall (DataType t, uint32_t c) const +{ + Glib::Mutex::Lock lm (_channel_mutex); + + vector::const_iterator i = _channel.begin (); + + uint32_t o = 0; + + while (1) { + + assert (i != _channel.end ()); + + if (i->type != t) { + ++i; + } else { + if (c == 0) { + return o; + } + --c; + } + + ++o; + } + + /* NOTREACHED */ + return -1; +} -- cgit v1.2.3