Index: /trunk/libffado/src/dice/dice_eap.h =================================================================== --- /trunk/libffado/src/dice/dice_eap.h (revision 1776) +++ /trunk/libffado/src/dice/dice_eap.h (revision 1779) @@ -206,14 +206,4 @@ public: - struct Route - { - enum eRouteSource src; - int srcChannel; - enum eRouteDestination dst; - int dstChannel; - int peak; - }; - typedef std::vector RouteVector; - typedef std::vector::iterator RouteVectorIterator; virtual bool read() {return read(m_base, m_offset);}; @@ -223,29 +213,50 @@ virtual void show(); - bool insertRoute(struct Route r) - {return insertRoute(r, m_routes.size());}; - bool insertRoute(struct Route r, unsigned int index); - bool replaceRoute(unsigned int old_index, struct Route new_route); - bool replaceRoute(struct Route old_route, struct Route new_route); - bool removeRoute(struct Route r); - bool removeRoute(unsigned int index); - int getRouteIndex(struct Route r); - struct Route getRoute(unsigned int index); - - unsigned int getNbRoutes() {return m_routes.size();}; - - struct Route getRouteForDestination(enum eRouteDestination dst, int channel); - RouteVector getRoutesForSource(enum eRouteSource src, int channel); - - struct Route decodeRoute(uint32_t val); - uint32_t encodeRoute(struct Route r); - public: - static enum eRouteDestination intToRouteDestination(int); - static enum eRouteSource intToRouteSource(int); + /** + @brief map for the routes + + The key is the destination as each destination can only have audio from one source. + Sources can be routed to several destinations though. + */ + typedef std::map RouteVectorV2; + + /** + @brief Set up a route between src and dest + + If a route with that destination exists, it will be replaced. If no route to that + destination exists, a new route will be established. + */ + bool setupRoute(unsigned char src, unsigned char dest); + /** + @brief Remove a route + + @todo is this really necessary? + */ + bool removeRoute(unsigned char src, unsigned char dest); + /** + @brief Remove the destinations route + */ + bool removeRoute(unsigned char dest); + + /** + @brief Return the source for the given destination + + Returns -1 if the destination is not connected. + */ + unsigned char getSourceForDestination(unsigned char dest); + /** + @brief Return a list of destinations for a given source + + Returns an empty list if no destination is connected to this source. + */ + std::vector getDestinationsForSource(unsigned char src); + + unsigned int getNbRoutes() {return m_routes2.size();}; + protected: EAP &m_eap; enum eRegBase m_base; unsigned int m_offset; - RouteVector m_routes; + RouteVectorV2 m_routes2; protected: DECLARE_DEBUG_MODULE_REFERENCE; @@ -341,7 +352,8 @@ virtual double getValue( const int, const int ); - bool hasNames() const { return true; } - std::string getRowName( const int ); - std::string getColName( const int ); + // @TODO: re-implement names + bool hasNames() const { return false; } + //std::string getRowName( const int ); + //std::string getColName( const int ); // TODO: implement connections. @@ -356,6 +368,6 @@ fb_quadlet_t *m_coeff; - std::map m_input_route_map; - std::map m_output_route_map; + //std::map m_input_route_map; + //std::map m_output_route_map; DECLARE_DEBUG_MODULE_REFERENCE; Index: /trunk/libffado/src/dice/focusrite/saffire_pro24.cpp =================================================================== --- /trunk/libffado/src/dice/focusrite/saffire_pro24.cpp (revision 1776) +++ /trunk/libffado/src/dice/focusrite/saffire_pro24.cpp (revision 1779) @@ -50,4 +50,5 @@ addSource("Mixer", 0, 16, eRS_Mixer); addSource("1394", 0, 8, eRS_ARX0); + addSource("Mute", 0, 1, eRS_Muted); } void SaffirePro24::SaffirePro24EAP::setupDestinations() { @@ -57,4 +58,5 @@ addDestination("Mixer", 0, 2, eRD_Mixer1, 16); addDestination("1394", 0, 16, eRD_ATX0); + addDestination("Mute", 0, 1, eRD_Muted); } Index: /trunk/libffado/src/dice/dice_eap.cpp =================================================================== --- /trunk/libffado/src/dice/dice_eap.cpp (revision 1776) +++ /trunk/libffado/src/dice/dice_eap.cpp (revision 1779) @@ -875,4 +875,6 @@ EAP::Mixer::updateNameCache() { + debugWarning("What is this function about?\n"); +#if 0 // figure out the number of i/o's int nb_inputs = m_eap.m_mixer_nb_tx; @@ -953,4 +955,5 @@ #endif } +#endif } @@ -973,5 +976,5 @@ printMessage("%s\n", tmp); - cnt = 0; + /*cnt = 0; for(int j=0; j < nb_inputs; j++) { cnt += snprintf(tmp+cnt, bufflen-cnt, "%s:%02d ", @@ -979,5 +982,5 @@ m_input_route_map[j].srcChannel); } - printMessage("%s\n", tmp); + printMessage("%s\n", tmp);*/ // display coefficients @@ -990,5 +993,5 @@ // construct the set of destinations std::string destinations; - for ( RouterConfig::RouteVectorIterator it = m_output_route_map[i].begin(); + /*for ( RouterConfig::RouteVectorIterator it = m_output_route_map[i].begin(); it != m_output_route_map[i].end(); ++it ) @@ -1001,5 +1004,5 @@ destinations += tmp; } - } + }*/ cnt += snprintf(tmp+cnt, bufflen-cnt, "=[%02d]=> %s ", i, destinations.c_str()); @@ -1076,4 +1079,5 @@ // Names +#if 0 std::string EAP::Mixer::getColName(const int col) { @@ -1095,4 +1099,5 @@ return tmp; } +#endif // @@ -1151,5 +1156,4 @@ EAP::Router::getDestinationName(const int dstid) { - debugWarning("TODO: Implement getDestinationName(0x%02x)\n", dstid); for (std::map::iterator it=m_destinations.begin(); it!=m_destinations.end(); ++it) { if (it->second == dstid) { @@ -1196,6 +1200,15 @@ stringlist EAP::Router::getDestinationsForSource(const std::string& srcname) { - debugWarning("TODO: Implement getDestinationsForSource(%s)\n", srcname.c_str()); - return stringlist(); + RouterConfig* rcfg = m_eap.getActiveRouterConfig(); + if(rcfg == NULL) { + debugError("Could not request active router configuration\n"); + return ""; + } + stringlist ret; + std::vector dests = rcfg->getDestinationsForSource(m_sources[srcname]); + for (int i=0; i>4); - int dstChannel = m_destinations[dstname]&0xf; - RouterConfig::Route r = rcfg->getRouteForDestination(dst, dstChannel); - if (r.src == eRS_Invalid) { - return ""; - } - return getSourceName((r.src<<4)+r.srcChannel); + int source = rcfg->getSourceForDestination(m_destinations[dstname]); + return getSourceName(source); } @@ -1220,15 +1228,4 @@ { debugWarning("TODO: Implement canConnect(0x%02x, 0x%02x)\n", source, dest); - /*if((unsigned)source >= m_sources.size()) { - debugWarning("source id out of range (%d)\n", source); - return false; - } - Source s = m_sources.at(source); - - if((unsigned)dest >= m_destinations.size()) { - debugWarning("destination id out of range (%d)\n", dest); - return false; - } - Destination d = m_destinations.at(dest);*/ // we can connect anything @@ -1240,4 +1237,5 @@ EAP::Router::setConnectionState(const int source, const int dest, const bool enable) { + debugOutput(DEBUG_LEVEL_VERBOSE,"Router::setConnectionState(0x%02x -> 0x%02x ? %i)\n", source, dest, enable); // get the routing configuration RouterConfig *rcfg = m_eap.getActiveRouterConfig(); @@ -1247,35 +1245,12 @@ } - RouterConfig::Route r = rcfg->getRouteForDestination(eRouteDestination(dest>>4), dest&0xf); - if ( r.srcChannel == -1 && r.dstChannel == -1 && enable ) { - r.src = eRouteSource(source>>4); - r.srcChannel = source&0xf; - r.dst = eRouteDestination(dest>>4); - r.dstChannel = dest&0xf; - int ret = rcfg->insertRoute(r); - m_eap.updateCurrentRouterConfig(*rcfg); - return ret; - } - if ( r.dst != (dest>>4) || r.dstChannel != (dest&0xf) ) { - debugError("Route exists but isn't correct? strange...\n"); - debugError(" wanted: 0x%02x got: 0x%02x\n", dest, (r.dst<<4)+r.dstChannel); - return false; - } - if ( !enable ) { - int ret = rcfg->removeRoute(r); - m_eap.updateCurrentRouterConfig(*rcfg); - return ret; - } - if ( enable ) { - int index = rcfg->getRouteIndex(r); - r.src = eRouteSource(source>>4); - r.srcChannel = (source&0xf); - int ret = rcfg->replaceRoute(index, r); - m_eap.updateCurrentRouterConfig(*rcfg); - return ret; - } - - // When we reach this point, something went wrong. Return false by default... - return false; + bool ret = false; + if (enable) { + ret = rcfg->setupRoute(source, dest); + } else { + ret = rcfg->removeRoute(source, dest); + } + m_eap.updateCurrentRouterConfig(*rcfg); + return ret; } @@ -1289,10 +1264,8 @@ return false; } - // Construct a route - RouterConfig::Route r = { eRouteSource(source>>4), source&0xf, eRouteDestination(dest>>4), dest&0xf }; - // get the routes index... - int idx = rcfg->getRouteIndex(r); - // ...and return true if it exists - return (idx>=0); + if (rcfg->getSourceForDestination(dest) == source) { + return true; + } + return false; } @@ -1422,7 +1395,9 @@ } } - //printMessage("Active router config:\n"); - //m_peak.read(); - //m_peak.show(); + printMessage("Active router config:\n"); + m_eap.getActiveRouterConfig()->show(); + printMessage("Active peak config:\n"); + m_peak.read(); + m_peak.show(); } @@ -1447,5 +1422,5 @@ { // first clear the current route vector - m_routes.clear(); + m_routes2.clear(); uint32_t nb_routes; @@ -1465,7 +1440,7 @@ } - // decode into the routing vector + // decode into the routing map for(unsigned int i=0; i < nb_routes; i++) { - m_routes.push_back(decodeRoute(tmp_entries[i])); + m_routes2[tmp_entries[i]&0xff] = (tmp_entries[i]>>8)&0xff; } return true; @@ -1475,7 +1450,11 @@ EAP::RouterConfig::write(enum eRegBase base, unsigned offset) { - uint32_t nb_routes = m_routes.size(); + uint32_t nb_routes = m_routes2.size(); if(nb_routes == 0) { - debugWarning("Writing 0 routes?\n"); + debugWarning("Writing 0 routes? This will deactivate routing and make the device very silent...\n"); + } + if (nb_routes > 128) { + debugError("More then 128 are not possible, only the first 128 routes will get saved!\n"); + nb_routes = 128; } uint32_t tmp_entries[nb_routes]; @@ -1483,10 +1462,14 @@ // encode from the routing vector int i=0; - for ( RouteVectorIterator it = m_routes.begin(); - it != m_routes.end(); - ++it ) - { - tmp_entries[i] = encodeRoute( *it ); - i++; + for (RouteVectorV2::iterator it=m_routes2.begin(); it!=m_routes2.end(); ++it) { + tmp_entries[i] = ((it->second<<8) + it->first)&0xffff; + ++i; + } + + uint32_t zeros[129]; + for (int i=0; i<129; ++i) zeros[i] = 0; + if(!m_eap.writeRegBlock(base, offset, zeros, 129*4)) { + debugError("Failed to write zeros to router config block\n"); + return false; } @@ -1504,199 +1487,49 @@ bool -EAP::RouterConfig::insertRoute(struct Route r, unsigned int index) -{ - unsigned int nb_routes = getNbRoutes(); - if(index > nb_routes) { - debugError("Index out of range\n"); - return false; - } - if (index == nb_routes) { // append - m_routes.push_back(r); - return true; - } - // insert - RouteVectorIterator pos = m_routes.begin() + index; - m_routes.insert(pos, r); +EAP::RouterConfig::setupRoute(unsigned char src, unsigned char dest) { + debugOutput(DEBUG_LEVEL_VERBOSE,"RouterConfig::setupRoute( 0x%02x, 0x%02x )\n", src, dest); + m_routes2[dest] = src; return true; } bool -EAP::RouterConfig::replaceRoute(unsigned int old_index, struct Route new_route) -{ - if(old_index >= getNbRoutes()) { - debugError("Index out of range\n"); - return false; - } - if(!removeRoute(old_index)) { - debugError("Could not remove old route\n"); - return false; - } - return insertRoute(new_route, old_index); -} - -bool -EAP::RouterConfig::replaceRoute(struct Route old_route, struct Route new_route) -{ - int idx = getRouteIndex(old_route); - if(idx < 0) { - debugWarning("Route not found\n"); - return false; - } - return replaceRoute((unsigned int)idx, new_route); -} - -bool -EAP::RouterConfig::removeRoute(struct Route r) -{ - int idx = getRouteIndex(r); - if(idx < 0) { - debugWarning("Route not found\n"); - return false; - } - return removeRoute((unsigned int)idx); -} - -bool -EAP::RouterConfig::removeRoute(unsigned int index) -{ - if(index >= getNbRoutes()) { - debugError("Index out of range\n"); - return false; - } - RouteVectorIterator pos = m_routes.begin() + index; - m_routes.erase(pos); +EAP::RouterConfig::removeRoute(unsigned char src, unsigned char dest) { + debugOutput(DEBUG_LEVEL_VERBOSE,"RouterConfig::removeRoute( 0x%02x, 0x%02x )\n", src, dest); + if (m_routes2.count(dest) > 0) { + if (src != m_routes2[dest]) { + return false; + } + return removeRoute(dest); + } return true; } -int -EAP::RouterConfig::getRouteIndex(struct Route r) -{ - int i = 0; - for ( RouteVectorIterator it = m_routes.begin(); - it != m_routes.end(); - ++it ) - { - struct Route t = *it; - if ((t.src == r.src) && (t.srcChannel == r.srcChannel) && (t.dst == r.dst) && (t.dstChannel == r.dstChannel)) return i; - i++; +bool +EAP::RouterConfig::removeRoute(unsigned char dest) { + debugOutput(DEBUG_LEVEL_VERBOSE,"RouterConfig::removeRoute( 0x%02x )\n", dest); + m_routes2.erase(dest); + if (m_routes2.count(dest) < 1) { + return false; + } + return true; +} + +unsigned char +EAP::RouterConfig::getSourceForDestination(unsigned char dest) { + if (m_routes2.count(dest) > 0) { + return m_routes2[dest]; } return -1; } -struct EAP::RouterConfig::Route -EAP::RouterConfig::getRoute(unsigned int idx) -{ - if( (idx < 0) || (idx >= m_routes.size()) ) { - debugWarning("Route index out of range (%d)\n", idx); - Route r = {eRS_Invalid, -1, eRD_Invalid, -1, 0}; - return r; - } - return m_routes.at(idx); -} - -#define CASE_INT_EQUAL_RETURN(_x) case (int)(_x): return _x; -enum eRouteDestination -EAP::RouterConfig::intToRouteDestination(int dst) -{ - switch(dst) { - CASE_INT_EQUAL_RETURN(eRD_AES); - CASE_INT_EQUAL_RETURN(eRD_ADAT); - CASE_INT_EQUAL_RETURN(eRD_Mixer0); - CASE_INT_EQUAL_RETURN(eRD_Mixer1); - CASE_INT_EQUAL_RETURN(eRD_InS0); - CASE_INT_EQUAL_RETURN(eRD_InS1); - CASE_INT_EQUAL_RETURN(eRD_ARM); - CASE_INT_EQUAL_RETURN(eRD_ATX0); - CASE_INT_EQUAL_RETURN(eRD_ATX1); - CASE_INT_EQUAL_RETURN(eRD_Muted); - default: return eRD_Invalid; - } -} - -enum eRouteSource -EAP::RouterConfig::intToRouteSource(int src) -{ - switch(src) { - CASE_INT_EQUAL_RETURN(eRS_AES); - CASE_INT_EQUAL_RETURN(eRS_ADAT); - CASE_INT_EQUAL_RETURN(eRS_Mixer); - CASE_INT_EQUAL_RETURN(eRS_InS0); - CASE_INT_EQUAL_RETURN(eRS_InS1); - CASE_INT_EQUAL_RETURN(eRS_ARM); - CASE_INT_EQUAL_RETURN(eRS_ARX0); - CASE_INT_EQUAL_RETURN(eRS_ARX1); - CASE_INT_EQUAL_RETURN(eRS_Muted); - default: return eRS_Invalid; - } -} - -struct EAP::RouterConfig::Route -EAP::RouterConfig::decodeRoute(uint32_t val) { - int routerval = val & 0xFFFF; - int peak = (val >> 16) & 0x0FFF; - int src_blk = (routerval >> 12) & 0xF; - int src_ch = (routerval >> 8) & 0xF; - int dst_blk = (routerval >> 4) & 0xF; - int dst_ch = (routerval >> 0) & 0xF; - struct Route r = {intToRouteSource(src_blk), src_ch, intToRouteDestination(dst_blk), dst_ch, peak}; - return r; -} - -uint32_t -EAP::RouterConfig::encodeRoute(struct Route r) { - if(r.src == eRS_Invalid || r.dst == eRD_Invalid) { - debugWarning("Encoding invalid source/dest (%d/%d)\n", r.src, r.dst); -// return 0xFFFFFFFF; - } - unsigned int src_blk = ((unsigned int)r.src) & 0xF; - unsigned int src_ch = ((unsigned int)r.srcChannel) & 0xF; - unsigned int dst_blk = ((unsigned int)r.dst) & 0xF; - unsigned int dst_ch = ((unsigned int)r.dstChannel) & 0xF; - uint32_t routerval = 0; - routerval |= (src_blk << 12); - routerval |= (src_ch << 8); - routerval |= (dst_blk << 4); - routerval |= (dst_ch << 0); - return routerval; -} - -struct EAP::RouterConfig::Route -EAP::RouterConfig::getRouteForDestination(enum eRouteDestination dst, int channel) -{ - for ( RouteVectorIterator it = m_routes.begin(); - it != m_routes.end(); - ++it ) - { - struct Route r = *it; - if((r.dst == (int)dst) && (r.dstChannel == channel)) { - debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "%s:%02d comes from %s:%02d\n", - dstBlockToString(r.dst), r.dstChannel, - srcBlockToString(r.src), r.srcChannel); - return r; - } - } - debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "%s:%02d source can't be found\n", - dstBlockToString((int)dst), channel); - struct Route r = {eRS_Invalid, -1, eRD_Invalid, -1, 0}; - return r; -} - -std::vector -EAP::RouterConfig::getRoutesForSource(enum eRouteSource src, int channel) -{ - std::vectorroutes; - for ( RouteVectorIterator it = m_routes.begin(); - it != m_routes.end(); - ++it ) - { - struct Route r = *it; - if((r.src == (int)src) && (r.srcChannel == channel)) { - debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "%s:%02d goes to %s:%02d\n", - srcBlockToString(r.src), r.srcChannel, - dstBlockToString(r.dst), r.dstChannel); - routes.push_back(r); - } - } - return routes; +std::vector +EAP::RouterConfig::getDestinationsForSource(unsigned char source) { + std::vector ret; + for (RouteVectorV2::iterator it=m_routes2.begin(); it!=m_routes2.end(); ++it) { + if (it->second == source) { + ret.push_back(it->first); + } + } + return ret; } @@ -1704,21 +1537,18 @@ EAP::RouterConfig::show() { - for ( RouteVectorIterator it = m_routes.begin(); - it != m_routes.end(); - ++it ) - { - struct Route r = *it; - debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "%s:%02d => %s:%02d\n", - srcBlockToString(r.src), r.srcChannel, - dstBlockToString(r.dst), r.dstChannel); - } -} - - + for ( RouteVectorV2::iterator it=m_routes2.begin(); it!=m_routes2.end(); ++it ) { + printMessage("0x%02x -> 0x%02x\n", it->second, it->first); + } +} + +// // ----------- peak space ------------- +// bool EAP::PeakSpace::read(enum eRegBase base, unsigned offset) { +#warning "Implement me again!" +#if 0 // first clear the current route vector m_routes.clear(); @@ -1746,4 +1576,5 @@ } // show(); +#endif return true; } @@ -1759,4 +1590,6 @@ EAP::PeakSpace::show() { + debugError("PeakSpace::show() is currently not implemented!\n"); +#if 0 for ( RouteVectorIterator it = m_routes.begin(); it != m_routes.end(); @@ -1764,9 +1597,10 @@ { struct Route r = *it; - debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "%s:%02d => %s:%02d : %06d\n", - srcBlockToString(r.src), r.srcChannel, - dstBlockToString(r.dst), r.dstChannel, - r.peak); - } + printMessage("%s:%02d => %s:%02d : %06d\n", + srcBlockToString(r.src), r.srcChannel, + dstBlockToString(r.dst), r.dstChannel, + r.peak); + } +#endif } Index: /trunk/libffado/support/mixer-qt4/ffado/widgets/crossbarrouter.py =================================================================== --- /trunk/libffado/support/mixer-qt4/ffado/widgets/crossbarrouter.py (revision 1776) +++ /trunk/libffado/support/mixer-qt4/ffado/widgets/crossbarrouter.py (revision 1779) @@ -37,11 +37,4 @@ self.output = output - if input is None: - input = int(self.interface.getSourceForDestination(output)) - self.setInput(input) - - def setInput(self, input): - #log.debug("VuMeter.setInput() %i->%i" % (self.output, input)) - self.input = input def updateLevel(self, value): @@ -80,6 +73,6 @@ self.layout.addWidget(self.lbl, 0, 0) - #self.vu = VuMeter(self.interface, self.interface.getDestinationIndex(outname), parent=self) - #self.layout.addWidget(self.vu, 0, 1) + self.vu = VuMeter(self.interface, outname, parent=self) + self.layout.addWidget(self.vu, 0, 1) sources = self.interface.getSourceNames() @@ -175,5 +168,5 @@ #log.debug("CrossbarRouter.updateLevels()") peakvalues = self.interface.getPeakValues() - #log.debug("Got %i peaks" % len(peakvalues)) + log.debug("Got %i peaks" % len(peakvalues)) for peak in peakvalues: #log.debug("peak = [%s,%s]" % (str(peak[0]),str(peak[1]))) Index: /trunk/libffado/support/dbus/controlserver.cpp =================================================================== --- /trunk/libffado/support/dbus/controlserver.cpp (revision 1776) +++ /trunk/libffado/support/dbus/controlserver.cpp (revision 1779) @@ -942,5 +942,13 @@ CrossbarRouter::getPeakValues() { - return std::vector< DBus::Struct >(); + std::map peakvalues = m_Slave.getPeakValues(); + std::vector< DBus::Struct > ret; + for (std::map::iterator it=peakvalues.begin(); it!=peakvalues.end(); ++it) { + DBus::Struct tmp; + tmp._1 = it->first; + tmp._2 = it->second; + ret.push_back(tmp); + } + return ret; /*std::vector< DBus::Struct > out; Control::CrossbarRouter::PeakValues values = m_Slave.getPeakValues();