X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fport_group.cc;h=a010b3c184b4be91743ca6820d020e178142c003;hb=7eb91510aa45676360a783355d30338d2cae9586;hp=c97b117fdc693c8e2b4576f54bad02b5e6d83f72;hpb=64dc5427e4f5339a16a018692dd94f476c53cae9;p=ardour.git diff --git a/gtk2_ardour/port_group.cc b/gtk2_ardour/port_group.cc index c97b117fdc..a010b3c184 100644 --- a/gtk2_ardour/port_group.cc +++ b/gtk2_ardour/port_group.cc @@ -30,6 +30,7 @@ #include "ardour/session.h" #include "ardour/auditioner.h" +#include "gui_thread.h" #include "port_group.h" #include "port_matrix.h" #include "time_axis_view.h" @@ -50,6 +51,14 @@ PortGroup::PortGroup (std::string const & n) } +PortGroup::~PortGroup() +{ + for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) { + delete *i; + } + _bundles.clear (); +} + /** Add a bundle to a group. * @param b Bundle. * @param allow_dups true to allow the group to contain more than one bundle with the same port, otherwise false. @@ -80,6 +89,14 @@ PortGroup::add_bundle (boost::shared_ptr b, boost::shared_ptr io, Gd add_bundle_internal (b, io, true, c, false); } +PortGroup::BundleRecord::BundleRecord (boost::shared_ptr b, boost::shared_ptr iop, Gdk::Color c, bool has_c) + : bundle (b) + , io (iop) + , colour (c) + , has_colour (has_c) +{ +} + void PortGroup::add_bundle_internal (boost::shared_ptr b, boost::shared_ptr io, bool has_colour, Gdk::Color colour, bool allow_dups) { @@ -90,7 +107,7 @@ PortGroup::add_bundle_internal (boost::shared_ptr b, boost::shared_ptrhas_same_ports (i->bundle) == false) { + while (i != _bundles.end() && b->has_same_ports ((*i)->bundle) == false) { ++i; } @@ -99,14 +116,9 @@ PortGroup::add_bundle_internal (boost::shared_ptr b, boost::shared_ptrChanged.connect (sigc::mem_fun (*this, &PortGroup::bundle_changed)); - - _bundles.push_back (r); + BundleRecord* br = new BundleRecord (b, io, colour, has_colour); + b->Changed.connect (br->changed_connection, invalidator (*this), ui_bind (&PortGroup::bundle_changed, this, _1), gui_context()); + _bundles.push_back (br); Changed (); } @@ -117,7 +129,7 @@ PortGroup::remove_bundle (boost::shared_ptr b) assert (b.get()); BundleList::iterator i = _bundles.begin (); - while (i != _bundles.end() && i->bundle != b) { + while (i != _bundles.end() && (*i)->bundle != b) { ++i; } @@ -125,7 +137,7 @@ PortGroup::remove_bundle (boost::shared_ptr b) return; } - i->changed_connection.disconnect (); + delete *i; _bundles.erase (i); Changed (); @@ -142,7 +154,7 @@ void PortGroup::clear () { for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) { - i->changed_connection.disconnect (); + delete *i; } _bundles.clear (); @@ -153,7 +165,7 @@ bool PortGroup::has_port (std::string const& p) const { for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) { - if (i->bundle->offers_port_alone (p)) { + if ((*i)->bundle->offers_port_alone (p)) { return true; } } @@ -165,7 +177,7 @@ boost::shared_ptr PortGroup::only_bundle () { assert (_bundles.size() == 1); - return _bundles.front().bundle; + return _bundles.front()->bundle; } @@ -174,7 +186,7 @@ PortGroup::total_channels () const { uint32_t n = 0; for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) { - n += i->bundle->nchannels (); + n += (*i)->bundle->nchannels (); } return n; @@ -184,7 +196,7 @@ boost::shared_ptr PortGroup::io_from_bundle (boost::shared_ptr b) const { BundleList::const_iterator i = _bundles.begin (); - while (i != _bundles.end() && i->bundle != b) { + while (i != _bundles.end() && (*i)->bundle != b) { ++i; } @@ -192,7 +204,56 @@ PortGroup::io_from_bundle (boost::shared_ptr b) const return boost::shared_ptr (); } - return i->io; + return (*i)->io; +} + +/** Remove bundles whose channels are already represented by other, larger bundles */ +void +PortGroup::remove_duplicates () +{ + BundleList::iterator i = _bundles.begin(); + while (i != _bundles.end()) { + + BundleList::iterator tmp = i; + ++tmp; + + bool remove = false; + + for (BundleList::iterator j = _bundles.begin(); j != _bundles.end(); ++j) { + + if ((*j)->bundle->nchannels() > (*i)->bundle->nchannels()) { + /* this bundle is larger */ + + uint32_t k = 0; + while (k < (*i)->bundle->nchannels()) { + /* see if this channel on *i has an equivalent on *j */ + uint32_t l = 0; + while (l < (*j)->bundle->nchannels() && (*i)->bundle->channel_ports (k) != (*j)->bundle->channel_ports (l)) { + ++l; + } + + if (l == (*j)->bundle->nchannels()) { + /* it does not */ + break; + } + + ++k; + } + + if (k == (*i)->bundle->nchannels ()) { + /* all channels on *i are represented by the larger bundle *j, so remove *i */ + remove = true; + break; + } + } + } + + if (remove) { + _bundles.erase (i); + } + + i = tmp; + } } @@ -204,6 +265,11 @@ PortGroupList::PortGroupList () } +PortGroupList::~PortGroupList() +{ + /* XXX need to clean up bundles, but ownership shared with PortGroups */ +} + void PortGroupList::set_type (DataType t) { @@ -272,7 +338,7 @@ PortGroupList::gather (ARDOUR::Session* session, bool inputs, bool allow_dups) route_bundles.push_back (io->bundle ()); - (*i)->foreach_processor (sigc::bind (sigc::mem_fun (*this, &PortGroupList::maybe_add_processor_to_list), &route_bundles, inputs, used_io)); + (*i)->foreach_processor (boost::bind (&PortGroupList::maybe_add_processor_to_list, this, _1, &route_bundles, inputs, used_io)); /* Work out which group to put these bundles in */ boost::shared_ptr g; @@ -351,13 +417,21 @@ PortGroupList::gather (ARDOUR::Session* session, bool inputs, bool allow_dups) std::string const p = ports[n]; - cout << p << "\n"; - if (!system->has_port(p) && !bus->has_port(p) && !track->has_port(p) && !ardour->has_port(p) && !other->has_port(p)) { + + /* special hack: ignore MIDI ports labelled Midi-Through. these + are basically useless and mess things up for default + connections. + */ + + if (p.find ("MIDI-Through") != string::npos) { + ++n; + continue; + } if (port_has_prefix (p, "system:") || port_has_prefix (p, "alsa_pcm") || @@ -383,11 +457,15 @@ PortGroupList::gather (ARDOUR::Session* session, bool inputs, bool allow_dups) other->add_bundle (make_bundle_from_ports (extra_other, inputs)); } - add_group_if_not_empty (system); + if (!allow_dups) { + system->remove_duplicates (); + } + + add_group_if_not_empty (other); add_group_if_not_empty (bus); add_group_if_not_empty (track); add_group_if_not_empty (ardour); - add_group_if_not_empty (other); + add_group_if_not_empty (system); emit_changed (); } @@ -465,13 +543,7 @@ void PortGroupList::clear () { _groups.clear (); - - for (std::vector::iterator i = _bundle_changed_connections.begin(); i != _bundle_changed_connections.end(); ++i) { - i->disconnect (); - } - - _bundle_changed_connections.clear (); - + _bundle_changed_connections.drop_connections (); emit_changed (); } @@ -513,11 +585,8 @@ PortGroupList::add_group (boost::shared_ptr g) { _groups.push_back (g); - g->Changed.connect (sigc::mem_fun (*this, &PortGroupList::emit_changed)); - - _bundle_changed_connections.push_back ( - g->BundleChanged.connect (sigc::mem_fun (*this, &PortGroupList::emit_bundle_changed)) - ); + g->Changed.connect (_changed_connections, invalidator (*this), boost::bind (&PortGroupList::emit_changed, this), gui_context()); + g->BundleChanged.connect (_bundle_changed_connections, invalidator (*this), ui_bind (&PortGroupList::emit_bundle_changed, this, _1), gui_context()); emit_changed (); }