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
This commit is contained in:
Carl Hetherington 2011-11-08 02:10:56 +00:00
parent 9fa8238d9d
commit 19e97d1d64
8 changed files with 79 additions and 61 deletions

View File

@ -388,11 +388,10 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp
}
for (list<boost::shared_ptr<IO> >::iterator j = i->ios.begin(); j != i->ios.end(); ++j) {
boost::shared_ptr<Bundle> 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<UserBundle> (*i) && (*i)->ports_are_inputs() == inputs) {
boost::shared_ptr<Bundle> 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<UserBundle> (*i) == 0 && (*i)->ports_are_inputs() == inputs) {
boost::shared_ptr<Bundle> 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<Bundle> 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<Bundle> b = make_bundle_from_ports (extra_system[*i], *i, inputs);
boost::shared_ptr<Bundle> 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<Bundle> b = make_bundle_from_ports (extra_other[*i], *i, inputs);
boost::shared_ptr<Bundle> 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<Bundle>
PortGroupList::bundle_for_type (boost::shared_ptr<Bundle> 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<Bundle> 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;
}

View File

@ -146,7 +146,6 @@ class PortGroupList : public sigc::trackable
void maybe_add_processor_to_list (
boost::weak_ptr<ARDOUR::Processor>, std::list<boost::shared_ptr<ARDOUR::IO> > *, bool, std::set<boost::shared_ptr<ARDOUR::IO> > &
);
boost::shared_ptr<ARDOUR::Bundle> bundle_for_type (boost::shared_ptr<ARDOUR::Bundle>, ARDOUR::DataType) const;
mutable PortGroup::BundleList _bundles;
List _groups;

View File

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

View File

@ -197,7 +197,7 @@ PortMatrixComponent::position_to_channel (double p, double, boost::shared_ptr<co
uint32_t const s = _matrix->count_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;
}

View File

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

View File

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

View File

@ -100,6 +100,7 @@ class Bundle : public PBD::ScopedConnectionList
void disconnect (boost::shared_ptr<Bundle>, AudioEngine &);
bool connected_to (boost::shared_ptr<Bundle>, AudioEngine &);
bool has_same_ports (boost::shared_ptr<Bundle>) const;
uint32_t type_channel_to_overall (DataType, uint32_t) const;
void set_name (std::string const &);

View File

@ -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<Channel>::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;
}