Attempt to fix some confusions caused by bundles containing
authorCarl Hetherington <carl@carlh.net>
Tue, 8 Nov 2011 02:10:56 +0000 (02:10 +0000)
committerCarl Hetherington <carl@carlh.net>
Tue, 8 Nov 2011 02:10:56 +0000 (02:10 +0000)
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
gtk2_ardour/port_group.h
gtk2_ardour/port_matrix_column_labels.cc
gtk2_ardour/port_matrix_component.cc
gtk2_ardour/port_matrix_grid.cc
gtk2_ardour/port_matrix_row_labels.cc
libs/ardour/ardour/bundle.h
libs/ardour/bundle.cc

index 8383d803a3e9a519892bcbd20b7d2e979abcaf5f..a3a7ca8e77cfa2ea64349458847f4bff537e0527 100644 (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;
-}
index 1deff384327d78a36761d1c2528733d7526bbdba..3e13c3a5e343181ea77a2902f98d7b0a18344434 100644 (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;
index 1cdf510c59606a0b86d3344f0a503155e4b067f0..99dc369f0a76625b06436911d87b5bbd92e89270 100644 (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));
                }
index 166488bef0bc256b632e2a50dfaa997e35c10941..2637a26d22e065871279872c4e747b97e00d5b5f 100644 (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;
                        }
index 67fa73c0977b3e310e6d4f7b095c37e2e353275a..a4ca3df1b810d021123df3b98f5ef3e5619d39fc 100644 (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);
                }
        }
index fcfeef13d074ba569d229c5c1df33979f58989bc..38b2dde6a7342e704f13ffe5094a03abc2a388c3 100644 (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;
                                }
 
index 6b8586a46a7ee78fab7bed28e923340e99d0cb76..821dd57896c62c217370c8e03897d763710a6dc4 100644 (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 &);
 
index d8666c5bbba8d9d5424085185b9e4dc1bec09780..d9fc86e2add44ae11bc13d655aa0265cfcda5df2 100644 (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;
+}