Index: trunk/libffado/src/ffadodevice.cpp =================================================================== --- trunk/libffado/src/ffadodevice.cpp (revision 554) +++ trunk/libffado/src/ffadodevice.cpp (revision 554) @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * Copyright (C) 2005-2007 by Pieter Palmers + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "ffadodevice.h" + +#include "libieee1394/configrom.h" +#include "libieee1394/ieee1394service.h" + +#include +#include + +IMPL_DEBUG_MODULE( FFADODevice, FFADODevice, DEBUG_LEVEL_VERBOSE ); + +FFADODevice::FFADODevice( std::auto_ptr< ConfigRom >( configRom ), + Ieee1394Service& ieee1394service, + int nodeId ) + : OscNode() + , m_pConfigRom( configRom ) + , m_p1394Service( &ieee1394service ) + , m_verboseLevel( DEBUG_LEVEL_NORMAL ) + , m_nodeId ( nodeId ) +{ + addOption(Util::OptionContainer::Option("id",std::string("dev?"))); + + std::ostringstream nodestr; + nodestr << "node" << nodeId; + setOscBase(nodestr.str()); + ConfigRom& c = getConfigRom(); + + addChildOscNode(&c); +} + + +ConfigRom& +FFADODevice::getConfigRom() const +{ + return *m_pConfigRom; +} + +bool +FFADODevice::loadFromCache() +{ + return false; +} + +bool +FFADODevice::saveCache() +{ + return false; +} + +bool +FFADODevice::setId( unsigned int id) +{ + bool retval; + // FIXME: decent ID system nescessary + std::ostringstream idstr; + idstr << "dev" << id; + debugOutput( DEBUG_LEVEL_VERBOSE, "Set id to %s...\n", idstr.str().c_str()); + + + retval=setOption("id",idstr.str()); + if (retval) { + setOscBase(idstr.str()); + } + return retval; +} + +void +FFADODevice::setVerboseLevel(int l) +{ + m_verboseLevel=l; + setDebugLevel(l); +// m_pConfigRom->setVerboseLevel(l); + m_p1394Service->setVerboseLevel(l); +} + +bool +FFADODevice::enableStreaming() { + return true; +} + +bool +FFADODevice::disableStreaming() { + return true; +} Index: trunk/libffado/src/devicemanager.h =================================================================== --- trunk/libffado/src/devicemanager.h (revision 529) +++ trunk/libffado/src/devicemanager.h (revision 554) @@ -40,11 +40,11 @@ class Ieee1394Service; -class IAvDevice; +class FFADODevice; namespace Streaming { class StreamProcessor; } -typedef std::vector< IAvDevice* > IAvDeviceVector; -typedef std::vector< IAvDevice* >::iterator IAvDeviceVectorIterator; +typedef std::vector< FFADODevice* > FFADODeviceVector; +typedef std::vector< FFADODevice* >::iterator FFADODeviceVectorIterator; class DeviceManager @@ -65,6 +65,6 @@ int getDeviceNodeId( int deviceNr ); - IAvDevice* getAvDevice( int nodeId ); - IAvDevice* getAvDeviceByIndex( int idx ); + FFADODevice* getAvDevice( int nodeId ); + FFADODevice* getAvDeviceByIndex( int idx ); unsigned int getAvDeviceCount(); @@ -72,11 +72,11 @@ protected: - IAvDevice* getDriverForDevice( std::auto_ptr( configRom ), + FFADODevice* getDriverForDevice( std::auto_ptr( configRom ), int id ); - IAvDevice* getSlaveDriver( std::auto_ptr( configRom ) ); + FFADODevice* getSlaveDriver( std::auto_ptr( configRom ) ); protected: Ieee1394Service* m_1394Service; - IAvDeviceVector m_avDevices; + FFADODeviceVector m_avDevices; OSC::OscServer* m_oscServer; @@ -86,5 +86,4 @@ void setVerboseLevel(int l); private: - int m_verboseLevel; DECLARE_DEBUG_MODULE; }; Index: trunk/libffado/src/libstreaming/MotuPort.h =================================================================== --- trunk/libffado/src/libstreaming/MotuPort.h (revision 445) +++ trunk/libffado/src/libstreaming/MotuPort.h (revision 554) @@ -52,5 +52,5 @@ int size) : AudioPort(name, direction), - MotuPortInfo(name, position, size) // TODO: add more port information parameters here if nescessary + MotuPortInfo( position, size) // TODO: add more port information parameters here if nescessary {}; @@ -76,5 +76,5 @@ int position) : MidiPort(name, direction), - MotuPortInfo(name, position, 0) // TODO: add more port information parameters here if nescessary + MotuPortInfo(position, 0) // TODO: add more port information parameters here if nescessary {}; @@ -101,5 +101,5 @@ int position) : ControlPort(name, direction), - MotuPortInfo(name, position, 2) // TODO: add more port information parameters here if nescessary + MotuPortInfo(position, 2) // TODO: add more port information parameters here if nescessary {}; Index: trunk/libffado/src/libstreaming/MotuPortInfo.h =================================================================== --- trunk/libffado/src/libstreaming/MotuPortInfo.h (revision 445) +++ trunk/libffado/src/libstreaming/MotuPortInfo.h (revision 554) @@ -60,5 +60,4 @@ * the name parameter is mandatory * - * @param name Port name * @param position Start position of port's data in iso event * @param format Format of data in iso event @@ -66,16 +65,14 @@ * @return */ - MotuPortInfo(std::string name, int position, int size) - : m_name(name), m_position(position), m_size(size) + MotuPortInfo( int position, int size) + : m_position(position), m_size(size) {}; virtual ~MotuPortInfo() {}; - std::string getName() {return m_name;}; int getPosition() {return m_position;}; int getSize() {return m_size;}; protected: - std::string m_name; int m_position; Index: trunk/libffado/src/libstreaming/AmdtpPort.h =================================================================== --- trunk/libffado/src/libstreaming/AmdtpPort.h (revision 445) +++ trunk/libffado/src/libstreaming/AmdtpPort.h (revision 554) @@ -53,5 +53,5 @@ enum E_Formats format) : AudioPort(name, direction), - AmdtpPortInfo(name, position, location, format) + AmdtpPortInfo(position, location, format) {}; @@ -80,5 +80,5 @@ enum E_Formats format) : MidiPort(name, direction), - AmdtpPortInfo(name, position, location, format) + AmdtpPortInfo(position, location, format) {}; Index: trunk/libffado/src/libstreaming/PortManager.cpp =================================================================== --- trunk/libffado/src/libstreaming/PortManager.cpp (revision 445) +++ trunk/libffado/src/libstreaming/PortManager.cpp (revision 554) @@ -25,4 +25,7 @@ #include "Port.h" #include + +#include +#include @@ -57,4 +60,34 @@ // } +bool PortManager::makeNameUnique(Port *port) +{ + bool done=false; + int idx=0; + std::string portname_orig=port->getName(); + + while(!done && idx<10000) { + bool is_unique=true; + + for ( PortVectorIterator it = m_Ports.begin(); + it != m_Ports.end(); + ++it ) + { + is_unique &= !((*it)->getName() == port->getName()); + } + + if (is_unique) { + done=true; + } else { + std::ostringstream portname; + portname << portname_orig << idx++; + + port->setName(portname.str()); + } + } + + if(idx<10000) return true; + else return false; +} + /** * @@ -66,8 +99,13 @@ assert(port); - debugOutput( DEBUG_LEVEL_VERBOSE, "Adding port %s\n",port->getName().c_str()); - m_Ports.push_back(port); - - return true; + debugOutput( DEBUG_LEVEL_VERBOSE, "Adding port %s, type: %d, dir: %d, dtype: %d\n", + port->getName().c_str(), port->getPortType(), port->getDirection(), port->getDataType()); + + if (makeNameUnique(port)) { + m_Ports.push_back(port); + return true; + } else { + return false; + } } Index: trunk/libffado/src/libstreaming/AmdtpStreamProcessor.cpp =================================================================== --- trunk/libffado/src/libstreaming/AmdtpStreamProcessor.cpp (revision 535) +++ trunk/libffado/src/libstreaming/AmdtpStreamProcessor.cpp (revision 554) @@ -756,5 +756,5 @@ { bool ok=true; - char byte; + quadlet_t byte; quadlet_t *target_event=NULL; @@ -788,18 +788,29 @@ for(j = (dbc & 0x07)+mp->getLocation(); j < nevents; j += 8) { - + + quadlet_t tmpval; + target_event=(quadlet_t *)(data + ((j * m_dimension) + mp->getPosition())); - + if(mp->canRead()) { // we can send a byte mp->readEvent(&byte); - *target_event=htonl( + byte &= 0xFF; + tmpval=htonl( IEC61883_AM824_SET_LABEL((byte)<<16, IEC61883_AM824_LABEL_MIDI_1X)); + + debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "MIDI port %s, pos=%d, loc=%d, dbc=%d, nevents=%d, dim=%d\n", + mp->getName().c_str(), mp->getPosition(), mp->getLocation(), dbc, nevents, m_dimension); + debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "base=%p, target=%p, value=%08X\n", + data, target_event, tmpval); + } else { // can't send a byte, either because there is no byte, // or because this would exceed the maximum rate - *target_event=htonl( + tmpval=htonl( IEC61883_AM824_SET_LABEL(0,IEC61883_AM824_LABEL_MIDI_NO_DATA)); } + + *target_event=tmpval; } Index: trunk/libffado/src/libstreaming/Port.cpp =================================================================== --- trunk/libffado/src/libstreaming/Port.cpp (revision 445) +++ trunk/libffado/src/libstreaming/Port.cpp (revision 554) @@ -35,5 +35,4 @@ m_BufferType(E_PointerBuffer), m_disabled(true), - m_initialized(false), m_buffersize(0), m_eventsize(0), @@ -49,6 +48,6 @@ m_rate_counter(0), m_rate_counter_minimum(0), - m_average_ratecontrol(false) - + m_average_ratecontrol(false), + m_State(E_Created) { @@ -63,6 +62,6 @@ */ bool Port::init() { - if (m_initialized) { - debugFatal("Port already initialized... (%s)\n",m_Name.c_str()); + if (m_State != E_Created) { + debugFatal("Port (%s) not in E_Created state: %d\n",m_Name.c_str(),m_State); return false; } @@ -98,9 +97,8 @@ } - m_initialized=true; - m_eventsize=getEventSize(); // this won't change, so cache it - - return m_initialized; + + m_State = E_Initialized; + return true; } @@ -112,4 +110,17 @@ }; +void Port::show() { + debugOutput(DEBUG_LEVEL_VERBOSE,"Name : %s\n", m_Name.c_str()); + debugOutput(DEBUG_LEVEL_VERBOSE,"Signal Type : %d\n", m_SignalType); + debugOutput(DEBUG_LEVEL_VERBOSE,"Buffer Type : %d\n", m_BufferType); + debugOutput(DEBUG_LEVEL_VERBOSE,"Enabled? : %d\n", m_disabled); + debugOutput(DEBUG_LEVEL_VERBOSE,"State? : %d\n", m_State); + debugOutput(DEBUG_LEVEL_VERBOSE,"Buffer Size : %d\n", m_buffersize); + debugOutput(DEBUG_LEVEL_VERBOSE,"Event Size : %d\n", m_eventsize); + debugOutput(DEBUG_LEVEL_VERBOSE,"Data Type : %d\n", m_DataType); + debugOutput(DEBUG_LEVEL_VERBOSE,"Port Type : %d\n", m_PortType); + debugOutput(DEBUG_LEVEL_VERBOSE,"Direction : %d\n", m_Direction); + debugOutput(DEBUG_LEVEL_VERBOSE,"Rate Control? : %d\n", m_do_ratecontrol); +} void Port::setVerboseLevel(int l) { @@ -120,6 +131,6 @@ debugOutput( DEBUG_LEVEL_VERBOSE, "Setting name to %s for port %s\n",name.c_str(),m_Name.c_str()); - if (m_initialized) { - debugFatal("Port already initialized... (%s)\n",m_Name.c_str()); + if (m_State != E_Created) { + debugFatal("Port (%s) not in E_Created state: %d\n",m_Name.c_str(),m_State); return false; } @@ -132,6 +143,6 @@ bool Port::setBufferSize(unsigned int newsize) { debugOutput( DEBUG_LEVEL_VERBOSE, "Setting buffersize to %d for port %s\n",newsize,m_Name.c_str()); - if (m_initialized) { - debugFatal("Port already initialized... (%s)\n",m_Name.c_str()); + if (m_State != E_Created) { + debugFatal("Port (%s) not in E_Created state: %d\n",m_Name.c_str(),m_State); return false; } @@ -157,6 +168,6 @@ bool Port::setDataType(enum E_DataType d) { debugOutput( DEBUG_LEVEL_VERBOSE, "Setting datatype to %d for port %s\n",(int) d,m_Name.c_str()); - if (m_initialized) { - debugFatal("Port already initialized... (%s)\n",m_Name.c_str()); + if (m_State != E_Created) { + debugFatal("Port (%s) not in E_Created state: %d\n",m_Name.c_str(),m_State); return false; } @@ -190,6 +201,6 @@ bool Port::setSignalType(enum E_SignalType s) { debugOutput( DEBUG_LEVEL_VERBOSE, "Setting signaltype to %d for port %s\n",(int)s,m_Name.c_str()); - if (m_initialized) { - debugFatal("Port already initialized... (%s)\n",m_Name.c_str()); + if (m_State != E_Created) { + debugFatal("Port (%s) not in E_Created state: %d\n",m_Name.c_str(),m_State); return false; } @@ -223,6 +234,6 @@ bool Port::setBufferType(enum E_BufferType b) { debugOutput( DEBUG_LEVEL_VERBOSE, "Setting buffer type to %d for port %s\n",(int)b,m_Name.c_str()); - if (m_initialized) { - debugFatal("Port already initialized... (%s)\n",m_Name.c_str()); + if (m_State != E_Created) { + debugFatal("Port (%s) not in E_Created state: %d\n",m_Name.c_str(),m_State); return false; } @@ -257,11 +268,11 @@ // If called on an initialised stream but the request isn't for a change silently // allow it (relied on by C API as used by jack backend driver) - if (m_initialized && m_use_external_buffer==b) + if (m_State==E_Initialized && m_use_external_buffer==b) return true; debugOutput( DEBUG_LEVEL_VERBOSE, "Setting external buffer use to %d for port %s\n",(int)b,m_Name.c_str()); - if (m_initialized) { - debugFatal("Port already initialized... (%s)\n",m_Name.c_str()); + if (m_State != E_Created) { + debugFatal("Port (%s) not in E_Created state: %d\n",m_Name.c_str(),m_State); return false; } @@ -284,5 +295,6 @@ /** * Set the external buffer address. - * only call this when specifying an external buffer before init() + * only call this when you have specified that you will use + * an external buffer before doing the init() * * @param buff @@ -296,6 +308,18 @@ // buffer handling api's for ringbuffers bool Port::writeEvent(void *event) { - assert(m_BufferType==E_RingBuffer); + +#ifdef DEBUG + if (m_State != E_Initialized) { + debugFatal("Port (%s) not in E_Initialized state: %d\n",m_Name.c_str(),m_State); + return false; + } + + if(m_BufferType!=E_RingBuffer) { + debugError("operation not allowed on non E_RingBuffer ports\n"); + show(); + return false; + } assert(m_ringbuffer); +#endif debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Writing event %08X with size %d to port %s\n",*((quadlet_t *)event),m_eventsize, m_Name.c_str()); @@ -305,15 +329,44 @@ bool Port::readEvent(void *event) { + +#ifdef DEBUG + if (m_State != E_Initialized) { + debugFatal("Port (%s) not in E_Initialized state: %d\n",m_Name.c_str(),m_State); + return false; + } + + if(m_BufferType!=E_RingBuffer) { + debugError("operation not allowed on non E_RingBuffer ports\n"); + show(); + return false; + } assert(m_ringbuffer); - +#endif + + unsigned int read=ffado_ringbuffer_read(m_ringbuffer, (char *)event, m_eventsize); - + debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Reading event %X with size %d from port %s\n",*((quadlet_t *)event),m_eventsize,m_Name.c_str()); + + return (read==m_eventsize); } int Port::writeEvents(void *event, unsigned int nevents) { - assert(m_BufferType==E_RingBuffer); + +#ifdef DEBUG + if (m_State != E_Initialized) { + debugFatal("Port (%s) not in E_Initialized state: %d\n",m_Name.c_str(),m_State); + return false; + } + + if(m_BufferType!=E_RingBuffer) { + debugError("operation not allowed on non E_RingBuffer ports\n"); + show(); + return false; + } assert(m_ringbuffer); +#endif + unsigned int bytes2write=m_eventsize*nevents; @@ -338,5 +391,18 @@ int Port::readEvents(void *event, unsigned int nevents) { + +#ifdef DEBUG + if (m_State != E_Initialized) { + debugFatal("Port (%s) not in E_Initialized state: %d\n",m_Name.c_str(),m_State); + return false; + } + if(m_BufferType!=E_RingBuffer) { + debugError("operation not allowed on non E_RingBuffer ports\n"); + show(); + return false; + } assert(m_ringbuffer); +#endif + unsigned int bytes2read=m_eventsize*nevents; Index: trunk/libffado/src/libstreaming/PortManager.h =================================================================== --- trunk/libffado/src/libstreaming/PortManager.h (revision 445) +++ trunk/libffado/src/libstreaming/PortManager.h (revision 554) @@ -48,4 +48,5 @@ virtual ~PortManager(); + virtual bool makeNameUnique(Port *port); virtual bool addPort(Port *port); virtual bool deletePort(Port *port); Index: trunk/libffado/src/libstreaming/Port.h =================================================================== --- trunk/libffado/src/libstreaming/Port.h (revision 445) +++ trunk/libffado/src/libstreaming/Port.h (revision 554) @@ -270,6 +270,7 @@ int readEvents(void *event, unsigned int nevents); ///< read multiple events - virtual void setVerboseLevel(int l); - + virtual void setVerboseLevel(int l); + virtual void show(); + protected: std::string m_Name; ///< Port name, [at construction] @@ -279,5 +280,4 @@ bool m_disabled; ///< is the port disabled?, [anytime] - bool m_initialized; ///< is the port initialized? [after init()] unsigned int m_buffersize; @@ -306,5 +306,16 @@ DECLARE_DEBUG_MODULE; - + + // the state machine + protected: + enum EStates { + E_Created, + E_Initialized, + E_Prepared, + E_Running, + E_Error + }; + + enum EStates m_State; }; Index: trunk/libffado/src/libstreaming/AmdtpPortInfo.h =================================================================== --- trunk/libffado/src/libstreaming/AmdtpPortInfo.h (revision 445) +++ trunk/libffado/src/libstreaming/AmdtpPortInfo.h (revision 554) @@ -54,11 +54,10 @@ }; - AmdtpPortInfo(std::string name, int position, int location, enum E_Formats format) - : m_name(name), m_position(position), m_location(location), m_format(format) + AmdtpPortInfo( int position, int location, enum E_Formats format) + : m_position(position), m_location(location), m_format(format) {}; virtual ~AmdtpPortInfo() {}; - std::string getName() {return m_name;}; int getLocation() {return m_location;}; int getPosition() {return m_position;}; @@ -66,6 +65,4 @@ protected: - std::string m_name; - int m_position; int m_location; Index: trunk/libffado/src/rme/rme_avdevice.h =================================================================== --- trunk/libffado/src/rme/rme_avdevice.h (revision 516) +++ trunk/libffado/src/rme/rme_avdevice.h (revision 554) @@ -26,5 +26,5 @@ #define RMEDEVICE_H -#include "iavdevice.h" +#include "ffadodevice.h" #include "debugmodule/debugmodule.h" @@ -46,5 +46,5 @@ }; -class RmeDevice : public IAvDevice { +class RmeDevice : public FFADODevice { public: @@ -60,5 +60,5 @@ virtual void showDevice(); - virtual bool setSamplingFrequency( ESamplingFrequency samplingFrequency ); + virtual bool setSamplingFrequency( int samplingFrequency ); virtual int getSamplingFrequency( ); Index: trunk/libffado/src/rme/rme_avdevice.cpp =================================================================== --- trunk/libffado/src/rme/rme_avdevice.cpp (revision 479) +++ trunk/libffado/src/rme/rme_avdevice.cpp (revision 554) @@ -53,5 +53,5 @@ Ieee1394Service& ieee1394service, int nodeId ) - : IAvDevice( configRom, ieee1394service, nodeId ) + : FFADODevice( configRom, ieee1394service, nodeId ) , m_model( NULL ) { @@ -128,10 +128,10 @@ bool -RmeDevice::setSamplingFrequency( ESamplingFrequency samplingFrequency ) +RmeDevice::setSamplingFrequency( int samplingFrequency ) { /* * Set the RME device's samplerate. */ - if (samplingFrequency == eSF_48000Hz) + if (samplingFrequency == 48000) return true; return false; Index: trunk/libffado/src/motu/motu_avdevice.h =================================================================== --- trunk/libffado/src/motu/motu_avdevice.h (revision 516) +++ trunk/libffado/src/motu/motu_avdevice.h (revision 554) @@ -26,5 +26,5 @@ #define MOTUDEVICE_H -#include "iavdevice.h" +#include "ffadodevice.h" #include "debugmodule/debugmodule.h" @@ -91,5 +91,5 @@ }; -class MotuDevice : public IAvDevice { +class MotuDevice : public FFADODevice { public: @@ -105,5 +105,5 @@ virtual void showDevice(); - virtual bool setSamplingFrequency( ESamplingFrequency samplingFrequency ); + virtual bool setSamplingFrequency( int samplingFrequency ); virtual int getSamplingFrequency( ); Index: trunk/libffado/src/motu/motu_avdevice.cpp =================================================================== --- trunk/libffado/src/motu/motu_avdevice.cpp (revision 480) +++ trunk/libffado/src/motu/motu_avdevice.cpp (revision 554) @@ -59,5 +59,5 @@ Ieee1394Service& ieee1394service, int nodeId) - : IAvDevice( configRom, ieee1394service, nodeId ) + : FFADODevice( configRom, ieee1394service, nodeId ) , m_motu_model( MOTUFW_MODEL_NONE ) , m_iso_recv_channel ( -1 ) @@ -177,5 +177,5 @@ bool -MotuDevice::setSamplingFrequency( ESamplingFrequency samplingFrequency ) +MotuDevice::setSamplingFrequency( int samplingFrequency ) { /* @@ -187,26 +187,26 @@ switch ( samplingFrequency ) { - case eSF_22050Hz: + case 22050: supported=false; break; - case eSF_24000Hz: + case 24000: supported=false; break; - case eSF_32000Hz: + case 32000: supported=false; break; - case eSF_44100Hz: + case 44100: new_rate = MOTUFW_RATE_BASE_44100 | MOTUFW_RATE_MULTIPLIER_1X; break; - case eSF_48000Hz: + case 48000: new_rate = MOTUFW_RATE_BASE_48000 | MOTUFW_RATE_MULTIPLIER_1X; break; - case eSF_88200Hz: + case 88200: new_rate = MOTUFW_RATE_BASE_44100 | MOTUFW_RATE_MULTIPLIER_2X; break; - case eSF_96000Hz: + case 96000: new_rate = MOTUFW_RATE_BASE_48000 | MOTUFW_RATE_MULTIPLIER_2X; break; - case eSF_176400Hz: + case 176400: // Currently only the Traveler supports 4x sample rates if (m_motu_model == MOTUFW_MODEL_TRAVELER) { @@ -216,5 +216,5 @@ supported=false; break; - case eSF_192000Hz: + case 192000: // Currently only the Traveler supports 4x sample rates if (m_motu_model == MOTUFW_MODEL_TRAVELER) { Index: trunk/libffado/src/ffadodevice.h =================================================================== --- trunk/libffado/src/ffadodevice.h (revision 554) +++ trunk/libffado/src/ffadodevice.h (revision 554) @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * Copyright (C) 2005-2007 by Pieter Palmers + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef FFADODEVICE_H +#define FFADODEVICE_H + +#include "libutil/OptionContainer.h" +#include "libosc/OscNode.h" + +class ConfigRom; +class Ieee1394Service; + +namespace Streaming { + class StreamProcessor; +} + +/*! +@brief Base class for device support + + This class should be subclassed to implement ffado support + for a specific device. + +*/ +class FFADODevice + : public Util::OptionContainer, + public OSC::OscNode +{ +public: + FFADODevice( std::auto_ptr< ConfigRom >( configRom ), + Ieee1394Service& ieee1394service, + int nodeId ); + + virtual ~FFADODevice() {}; + + /// Returns the 1394 service of the FFADO device + virtual Ieee1394Service& get1394Service() + { return *m_p1394Service; }; + /// Returns the ConfigRom object of the device node. + virtual ConfigRom& getConfigRom() const; + + /** + * @brief Called by DeviceManager to load device model from cache. + * + * This function is called before discover in order to speed up + * system initializing. + * + * @returns true if device was cached and successfully loaded from cache + */ + virtual bool loadFromCache(); + + /** + * @brief Called by DeviceManager to allow device driver to save a cache version + * of the current configuration. + * + * @returns true if caching was successful. False doesn't mean an error just, + * the driver was unable to store the configuration + */ + virtual bool saveCache(); + + /** + * @brief This is called by the DeviceManager to discover & configure the device + * + * @return true if the device was discovered successfuly + */ + virtual bool discover() = 0; + + /** + * @brief Set the samping frequency + * @param samplingFrequency + * @return true if successful + */ + virtual bool setSamplingFrequency( int samplingFrequency ) = 0; + /** + * @brief get the samplingfrequency as an integer + * @return the sampling frequency as integer + */ + virtual int getSamplingFrequency( ) = 0; + + /** + * @brief This is called by the device manager to give the device a unique ID. + * + * The purpose of this is to allow for unique port naming + * in case there are multiple identical devices on the bus. + * Some audio API's (e.g. jack) don't work properly when the + * port names are not unique. + * + * Say you have two devices having a port named OutputLeft. + * This can cause the streaming + * part to present two OutputLeft ports to the audio API, + * which won't work. This ID will allow you to construct + * the port names as 'dev1_OutputLeft' and 'dev2_OutputLeft' + * + * @note Currently this is a simple integer that is equal to + * the position of the device in the devicemanager's + * device list. Therefore it is dependant on the order + * in which the devices are detected. The side-effect + * of this is that it is dependant on the bus topology + * and history (e.g. busresets etc). This makes that + * these ID's are not fixed to a specific physical device. + * At some point, we will replaced this with a GUID based + * approach, which is tied to a physical device and is + * bus & time independant. + * + * @param id + * @return true if successful + */ + bool setId(unsigned int id); + + /** + * @brief Outputs the device configuration to stderr/stdout [debug helper] + * + * This function prints out a (detailed) description of the + * device detected, and its configuration. + */ + virtual void showDevice() = 0; + + /** + * @brief Lock the device + * + * This is called by the streaming layer before we start manipulating + * and/or using the device. + * + * It should implement the mechanisms provided by the device to + * make sure that no other controller claims control of the device. + * + * @return true if successful, false if not + */ + virtual bool lock() = 0; + + /** + * @brief Unlock the device + * + * This is called by the streaming layer after we finish manipulating + * and/or using the device. + * + * It should implement the mechanisms provided by the device to + * give up exclusive control of the device. + * + * @return true if successful, false if not + */ + virtual bool unlock() = 0; + + /** + * @brief Enable streaming on all 'started' streams + * + * Enables the ISO streaming on all streams that are 'started' + * using startStreamByIndex. This is useful to control a 'master enable' + * function on the device. + * + * @return true if successful + */ + virtual bool enableStreaming(); + + /** + * @brief Disable streaming on all streams + * + * Disables ISO streaming on all streams. + * This is useful to control a 'master enable' + * function on the device. + * + * @return true if successful + */ + virtual bool disableStreaming(); + + /** + * @brief Prepare the device + * + * This is called by the streaming layer after the configuration + * parameters (e.g. sample rate) are set, and before + * getStreamProcessor[*] functions are called. + * + * It should be used to prepare the device's streamprocessors + * based upon the device's current configuration. Normally + * the streaming layer will not change the device's configuration + * after calling this function. + * + * @return true if successful, false if not + */ + virtual bool prepare() = 0; + + /** + * @brief Returns the number of ISO streams implemented/used by this device + * + * Most likely this is 2 streams, i.e. one transmit stream and one + * receive stream. However there are devices that implement more, for + * example BeBoB's implement 4 streams: + * - 2 audio streams (1 xmit/1 recv) + * - 2 sync streams (1 xmit/1 recv), which are an optional sync source + * for the device. + * + * @note you have to have a StreamProcessor for every stream. I.e. + * getStreamProcessorByIndex(i) should return a valid StreamProcessor + * for i=0 to i=getStreamCount()-1 + * + * @return number of streams available (both transmit and receive) + */ + virtual int getStreamCount() = 0; + + /** + * @brief Returns the StreamProcessor object for the stream with index i + * + * @note a streamprocessor returned by getStreamProcessorByIndex(i) + * cannot be the same object as one returned by + * getStreamProcessorByIndex(j) if i isn't equal to j + * @note you cannot have two streamprocessors handling the same ISO + * channel (on the same port) + * + * @param i : Stream index + * @pre @ref i smaller than getStreamCount() + * @return a StreamProcessor object if successful, NULL otherwise + */ + virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i) = 0; + + /** + * @brief starts the stream with index i + * + * This function is called by the streaming layer when this stream should + * be started, i.e. the device should start sending data or should be prepared to + * be ready to receive data. + * + * It returns the channel number that was assigned for this stream. + * Channel allocation should be done using the allocation functions provided by the + * Ieee1394Service object that is passed in the constructor. + * + * @param i : Stream index + * @pre @ref i smaller than getStreamCount() + * @return true if successful, false if not + */ + virtual bool startStreamByIndex(int i) = 0; + + /** + * @brief stops the stream with index @ref i + * + * @param i : Stream index + * @pre @ref i smaller than getStreamCount() + * @return true if successful, false if not + */ + virtual bool stopStreamByIndex(int i) = 0; + + /** + * set verbosity level + */ + virtual void setVerboseLevel(int l); + + /** + * @brief return the node id of this device + * + * @return the node id + */ + int getNodeId() { return m_nodeId;}; + +protected: + std::auto_ptr( m_pConfigRom ); + Ieee1394Service* m_p1394Service; + int m_verboseLevel; + int m_nodeId; + + DECLARE_DEBUG_MODULE; +}; + +#endif Index: trunk/libffado/src/metrichalo/mh_avdevice.h =================================================================== --- trunk/libffado/src/metrichalo/mh_avdevice.h (revision 516) +++ trunk/libffado/src/metrichalo/mh_avdevice.h (revision 554) @@ -25,5 +25,5 @@ #define MHDEVICE_H -#include "iavdevice.h" +#include "ffadodevice.h" #include "debugmodule/debugmodule.h" @@ -45,5 +45,5 @@ }; -class MHAvDevice : public IAvDevice { +class MHAvDevice : public FFADODevice { public: MHAvDevice( std::auto_ptr( configRom ), @@ -58,5 +58,5 @@ virtual void showDevice(); - virtual bool setSamplingFrequency( ESamplingFrequency samplingFrequency ); + virtual bool setSamplingFrequency( int ); virtual int getSamplingFrequency( ); Index: trunk/libffado/src/metrichalo/mh_avdevice.cpp =================================================================== --- trunk/libffado/src/metrichalo/mh_avdevice.cpp (revision 479) +++ trunk/libffado/src/metrichalo/mh_avdevice.cpp (revision 554) @@ -53,5 +53,5 @@ Ieee1394Service& ieee1394service, int nodeId ) - : IAvDevice( configRom, ieee1394service, nodeId ) + : FFADODevice( configRom, ieee1394service, nodeId ) , m_model( NULL ) @@ -125,5 +125,5 @@ bool -MHAvDevice::setSamplingFrequency( ESamplingFrequency samplingFrequency ) +MHAvDevice::setSamplingFrequency( int samplingFrequency ) { Index: trunk/libffado/src/debugmodule/debugmodule.h =================================================================== --- trunk/libffado/src/debugmodule/debugmodule.h (revision 494) +++ trunk/libffado/src/debugmodule/debugmodule.h (revision 554) @@ -34,8 +34,11 @@ typedef short debug_level_t; +#define DEBUG_MAX_MESSAGE_LENGTH 256 + /* MB_NEXT() relies on the fact that MB_BUFFERS is a power of two */ #define MB_BUFFERS (1<<16) + #define MB_NEXT(index) ((index+1) & (MB_BUFFERS-1)) -#define MB_BUFFERSIZE 256 /* message length limit */ +#define MB_BUFFERSIZE DEBUG_MAX_MESSAGE_LENGTH /* message length limit */ #define debugFatal( format, args... ) \ @@ -99,4 +102,5 @@ m_debugModule.getLevel( ) +#define flushDebugOutput() DebugModuleManager::instance()->flush() #ifdef DEBUG @@ -203,5 +207,5 @@ bool setMgrDebugLevel( std::string name, debug_level_t level ); - void sync(); + void flush(); protected: @@ -227,4 +231,5 @@ pthread_t mb_writer_thread; pthread_mutex_t mb_write_lock; + pthread_mutex_t mb_flush_lock; pthread_cond_t mb_ready_cond; Index: trunk/libffado/src/debugmodule/debugmodule.cpp =================================================================== --- trunk/libffado/src/debugmodule/debugmodule.cpp (revision 494) +++ trunk/libffado/src/debugmodule/debugmodule.cpp (revision 554) @@ -30,4 +30,12 @@ #include +#include + +//#define DO_MESSAGE_BUFFER_PRINT + +#ifndef DO_MESSAGE_BUFFER_PRINT + #warning Printing debug info without ringbuffer, not RT-safe! +#endif + using namespace std; @@ -111,6 +119,12 @@ fname=f; } - - DebugModuleManager::instance()->print( "%s (%s)[%4d] %s: ", getPreSequence( level ), + + // add a timing timestamp + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + uint32_t ts_usec=(uint32_t)(ts.tv_sec * 1000000LL + ts.tv_nsec / 1000LL); + + DebugModuleManager::instance()->print( "%010lu: %s (%s)[%4d] %s: ", + ts_usec, getPreSequence( level ), fname, line, function ); DebugModuleManager::instance()->va_print( format, arg ); @@ -195,4 +209,5 @@ pthread_mutex_init(&mb_write_lock, NULL); + pthread_mutex_init(&mb_flush_lock, NULL); pthread_cond_init(&mb_ready_cond, NULL); @@ -284,7 +299,7 @@ void -DebugModuleManager::sync() -{ - mb_flush(); +DebugModuleManager::flush() +{ +// mb_flush(); } @@ -293,8 +308,17 @@ { /* called WITHOUT the mb_write_lock */ + + /* the flush lock is to allow a flush from multiple threads + * this allows a code section that outputs a lot of debug messages + * and that can be blocked to flush the buffer itself such that it + * does not overflow. + */ + DebugModuleManager *m=DebugModuleManager::instance(); + pthread_mutex_lock(&m->mb_flush_lock); while (mb_outbuffer != mb_inbuffer) { fputs(mb_buffers[mb_outbuffer], stderr); mb_outbuffer = MB_NEXT(mb_outbuffer); } + pthread_mutex_unlock(&m->mb_flush_lock); } @@ -346,4 +370,5 @@ } +#ifdef DO_MESSAGE_BUFFER_PRINT while (ntries) { // try a few times if (pthread_mutex_trylock(&mb_write_lock) == 0) { @@ -358,12 +383,13 @@ } } - if (ntries==0) { /* lock collision */ -// atomic_add(&mb_overruns, 1); + // atomic_add(&mb_overruns, 1); // FIXME: atomicity mb_overruns++; // skip the atomicness for now } -} - +#else + fprintf(stderr,msg); +#endif +} void @@ -386,5 +412,6 @@ return; } - + +#ifdef DO_MESSAGE_BUFFER_PRINT while (ntries) { // try a few times if (pthread_mutex_trylock(&mb_write_lock) == 0) { @@ -405,4 +432,7 @@ mb_overruns++; // skip the atomicness for now } +#else + fprintf(stderr,msg); +#endif } Index: trunk/libffado/src/libavc/descriptors/avc_descriptor_cmd.h =================================================================== --- trunk/libffado/src/libavc/descriptors/avc_descriptor_cmd.h (revision 503) +++ trunk/libffado/src/libavc/descriptors/avc_descriptor_cmd.h (revision 503) @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2007 by Pieter Palmers + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVCDESCRIPTORCMD_H +#define AVCDESCRIPTORCMD_H + +#include "../general/avc_generic.h" + +#include + +namespace AVC { + + +// defined in avc1394.h +// #define AVC1394_CMD_OPEN_DESCRIPTOR 0x08 +// #define AVC1394_CMD_READ_DESCRIPTOR 0x09 +// #define AVC1394_CMD_WRITE_DESCRIPTOR 0x0A +// #define AVC1394_CMD_SEARCH_DESCRIPTOR 0x0B +// #define AVC1394_CMD_OBJECT_NUMBER_SELECT 0x0D + +// not yet defined +#define AVC1394_CMD_CREATE_DESCRIPTOR 0x0C +#define AVC1394_CMD_OPEN_INFOBLOCK 0x05 +#define AVC1394_CMD_READ_INFOBLOCK 0x06 +#define AVC1394_CMD_WRITE_INFOBLOCK 0x07 + +class AVCDescriptorSpecifier; + +class OpenDescriptorCmd: public AVCCommand +{ +public: + enum EMode { + eClose = 0x00, + eRead = 0x01, + eWrite = 0x03, + }; + + enum EStatus { + eReady = 0x00, + eReadOpened = 0x01, + eNonExistent = 0x04, + eListOnly = 0x05, + eAtCapacity = 0x11, + eWriteOpened = 0x33, + }; + + OpenDescriptorCmd(Ieee1394Service& ); + virtual ~OpenDescriptorCmd(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual bool clear(); + + virtual const char* getCmdName() const + { return "OpenDescriptorCmd"; } + + virtual void setMode( enum EMode m ) {m_mode=m;}; + AVCDescriptorSpecifier *m_specifier; + enum EMode m_mode; + + byte_t m_status; + byte_t m_reserved; + uint16_t m_locked_node_id; + +private: +}; + +class ReadDescriptorCmd: public AVCCommand +{ +public: + enum EReadStatus { + eComplete = 0x10, + eMoreToRead = 0x11, + eTooLarge = 0x12, + eInvalid = 0xFF, + }; + + ReadDescriptorCmd(Ieee1394Service& ieee1394service); + virtual ~ReadDescriptorCmd(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual bool clear(); + + enum EReadStatus getStatus(); + + virtual const char* getCmdName() const + { return "ReadDescriptorCmd"; } + + byte_t m_status; + byte_t m_reserved; + uint16_t m_data_length; + uint16_t m_address; + + byte_t *m_data; + + AVCDescriptorSpecifier *m_specifier; +private: + +}; + +} + +#endif // AVCDESCRIPTORCMD_H Index: trunk/libffado/src/libavc/descriptors/avc_descriptor.cpp =================================================================== --- trunk/libffado/src/libavc/descriptors/avc_descriptor.cpp (revision 524) +++ trunk/libffado/src/libavc/descriptors/avc_descriptor.cpp (revision 524) @@ -0,0 +1,537 @@ +/* + * Copyright (C) 2007 by Pieter Palmers + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_descriptor.h" +#include "avc_descriptor_cmd.h" + +#include "../general/avc_unit.h" +#include "../general/avc_subunit.h" + +#include "../util/avc_serialize.h" +#include "libieee1394/ieee1394service.h" +#include "libieee1394/configrom.h" + +namespace AVC { + +AVCDescriptorSpecifier::AVCDescriptorSpecifier( enum EType type ) + : m_type ( type ) + , m_listid_size ( 0 ) + , m_objectid_size ( 0 ) + , m_entrypos_size ( 0 ) + , m_info_block_type ( 0 ) + , m_info_block_instance ( 0 ) + , m_info_block_position ( 0 ) +{ + +} + +bool +AVCDescriptorSpecifier::serialize( IOSSerialize& se ) +{ + se.write( (byte_t)m_type, "AVCDescriptorSpecifier descriptor_specifier_type" ); + switch ( m_type ) { + case eIndentifier: + // nothing to serialize + return true; + case eInfoBlockByType: + se.write( m_info_block_type, "AVCDescriptorSpecifier info_block_type" ); + se.write( m_info_block_instance, "AVCDescriptorSpecifier instance_count" ); + return true; + case eInfoBlockByPosition: + se.write( m_info_block_position, "AVCDescriptorSpecifier info_block_position" ); + return true; + case eSubunit0x80: + // nothing to serialize + return true; + case eInvalid: + default: + debugError("Unsupported Descriptor Specifier type: 0x%02X\n",m_type); + return false; + } +} + +bool +AVCDescriptorSpecifier::deserialize( IISDeserialize& de ) +{ + de.read( (byte_t *)&m_type ); + switch ( m_type ) { + case eIndentifier: + // nothing to deserialize + return true; + case eInfoBlockByType: + de.read( &m_info_block_type); + de.read( &m_info_block_instance ); + case eInfoBlockByPosition: + de.read( &m_info_block_position); + + return true; + case eSubunit0x80: + // nothing to deserialize + return true; + case eInvalid: + default: + debugError("Unsupported Descriptor Specifier type: 0x%02X\n",m_type); + return false; + } + + return true; +} + +AVCDescriptorSpecifier* +AVCDescriptorSpecifier::clone() const +{ + return new AVCDescriptorSpecifier( *this ); +} + +//---------------------- +AVCDescriptor::AVCDescriptor( Unit* unit ) + : IBusData() + , m_unit( unit ) + , m_subunit ( NULL ) + , m_specifier ( AVCDescriptorSpecifier::eInvalid ) + , m_data ( NULL ) + , m_descriptor_length(0) + , m_loaded ( false ) +{ +} + +AVCDescriptor::AVCDescriptor( Unit* unit, Subunit* subunit ) + : IBusData() + , m_unit( unit ) + , m_subunit ( subunit ) + , m_specifier ( AVCDescriptorSpecifier::eInvalid ) + , m_data ( NULL ) + , m_descriptor_length(0) + , m_loaded ( false ) +{ +} + +AVCDescriptor::AVCDescriptor( Unit* unit, Subunit* subunit, + AVCDescriptorSpecifier s ) + : IBusData() + , m_unit( unit ) + , m_subunit ( subunit ) + , m_specifier ( s ) + , m_data ( NULL ) + , m_descriptor_length(0) + , m_loaded ( false ) +{ +} + +AVCDescriptor::~AVCDescriptor() +{ + if (m_data != NULL) free(m_data); +} +bool +AVCDescriptor::reload() +{ + m_loaded=false; + return load(); +} + +bool +AVCDescriptor::load() +{ + bool result; + + if (m_loaded) { + debugOutput(DEBUG_LEVEL_VERBOSE, "Descriptor already loaded, not re-loading...\n" ); + return true; + } + + OpenDescriptorCmd openDescCmd(m_unit->get1394Service()); + + debugOutput(DEBUG_LEVEL_VERBOSE, " Open descriptor (%s)\n",getDescriptorName()); + openDescCmd.setMode( OpenDescriptorCmd::eRead ); + openDescCmd.m_specifier=&m_specifier; + openDescCmd.setNodeId( m_unit->getConfigRom().getNodeId() ); + openDescCmd.setCommandType( AVCCommand::eCT_Control ); + openDescCmd.setSubunitType( getSubunitType() ); + openDescCmd.setSubunitId( getSubunitId() ); + openDescCmd.setVerbose( getVerboseLevel() ); + + result=openDescCmd.fire(); + + if (!result || (openDescCmd.getResponse() != AVCCommand::eR_Accepted)) { + debugOutput(DEBUG_LEVEL_VERBOSE, " Could not open descriptor\n"); + return false; + } + + debugOutput(DEBUG_LEVEL_VERBOSE, " Read status descriptor\n"); + ReadDescriptorCmd readDescCmd(m_unit->get1394Service()); + readDescCmd.m_specifier=&m_specifier; + readDescCmd.setNodeId( m_unit->getConfigRom().getNodeId() ); + readDescCmd.setCommandType( AVCCommand::eCT_Control ); + readDescCmd.setSubunitType( getSubunitType() ); + readDescCmd.setSubunitId( getSubunitId() ); + readDescCmd.setVerbose( getVerboseLevel() ); + readDescCmd.m_data_length=2; + readDescCmd.m_address=0; + + result=readDescCmd.fire(); + + if (!result || (readDescCmd.getResponse() != AVCCommand::eR_Accepted)) { + debugOutput(DEBUG_LEVEL_VERBOSE, " Could not read descriptor\n"); + return false; + } + + size_t bytes_read=readDescCmd.m_data_length; + if (bytes_read < 2) { + debugOutput(DEBUG_LEVEL_VERBOSE, " Descriptor length field not present\n"); + return false; + } + + // obtain descriptor length + m_descriptor_length=(readDescCmd.m_data[0]<<8) + (readDescCmd.m_data[1]); + debugOutput(DEBUG_LEVEL_VERBOSE, " Descriptor length: %u\n", m_descriptor_length); + + if (m_data != NULL) free(m_data); + + m_data=(byte_t *)calloc(m_descriptor_length, 1); + if (m_data == NULL) { + debugError("Could not allocate memory for descriptor\n"); + return false; + } + + // we reread everything from here + bytes_read=0; + while(bytes_readgetConfigRom().getNodeId() ); + readDescCmd.setCommandType( AVCCommand::eCT_Control ); + readDescCmd.setSubunitType( getSubunitType() ); + readDescCmd.setSubunitId( getSubunitId() ); + readDescCmd.setVerbose( getVerboseLevel() ); + readDescCmd.m_data_length=m_descriptor_length-bytes_read; + // account for the length field + readDescCmd.m_address=bytes_read+2; + + result=readDescCmd.fire(); + + if (!result || (readDescCmd.getResponse() != AVCCommand::eR_Accepted)) { + debugOutput(DEBUG_LEVEL_VERBOSE, " Could not read descriptor data\n"); + return false; + } + + // copy the payload + + if (bytes_read+readDescCmd.m_data_length>m_descriptor_length) { + debugWarning("Device returned too much data, truncating\n"); + readDescCmd.m_data_length=m_descriptor_length-bytes_read; + } + + debugOutput(DEBUG_LEVEL_VERBOSE, " copying %u bytes to internal buffer offset %u\n",readDescCmd.m_data_length, bytes_read); + + memcpy(m_data+bytes_read,readDescCmd.m_data, readDescCmd.m_data_length); + bytes_read += readDescCmd.m_data_length; + + if((readDescCmd.getStatus() != ReadDescriptorCmd::eMoreToRead) + && ( bytes_readgetConfigRom().getNodeId() ); + openDescCmd.setCommandType( AVCCommand::eCT_Control ); + openDescCmd.setSubunitType( getSubunitType() ); + openDescCmd.setSubunitId( getSubunitId() ); + openDescCmd.setVerbose( getVerboseLevel() ); + + result=openDescCmd.fire(); + + if (!result || (openDescCmd.getResponse() != AVCCommand::eR_Accepted)) { + debugOutput(DEBUG_LEVEL_VERBOSE, " Could not close descriptor\n"); + return false; + } + + debugOutput(DEBUG_LEVEL_VERBOSE, " Parse descriptor\n"); + // parse the descriptor + BufferDeserialize de( m_data, m_descriptor_length ); + result = deserialize( de ); + if (!result) { + debugOutput(DEBUG_LEVEL_VERBOSE, " Could not parse descriptor\n"); + return false; + } + +#ifdef DEBUG + if(getDebugLevel() >= DEBUG_LEVEL_VERY_VERBOSE) { + StringSerializer se_dbg; + serialize( se_dbg ); + + // output the debug message in smaller chunks to avoid problems + // with a max message size + unsigned int chars_to_write=se_dbg.getString().size(); + unsigned int chars_written=0; + while (chars_writtengetSubunitType()); +} + +subunit_id_t +AVCDescriptor::getSubunitId() const +{ + return (m_subunit==NULL?0xFF:m_subunit->getSubunitId()); +} + +bool +AVCDescriptor::setVerboseLevel( int verboseLevel ) +{ + setDebugLevel(verboseLevel); + return true; +} + +int +AVCDescriptor::getVerboseLevel() +{ + return getDebugLevel(); +} + +// --- Info block +AVCInfoBlock::AVCInfoBlock( ) + : IBusData() + , m_compound_length ( 0 ) + , m_info_block_type ( 0 ) + , m_primary_field_length ( 0 ) + , m_supported_info_block_type ( 0xFFFF ) +{} + +AVCInfoBlock::AVCInfoBlock( uint16_t supported_type ) + : IBusData() + , m_compound_length ( 0 ) + , m_info_block_type ( 0 ) + , m_primary_field_length ( 0 ) + , m_supported_info_block_type ( supported_type ) +{} + +bool +AVCInfoBlock::serialize( IOSSerialize& se ) +{ + bool result=true; + if((m_supported_info_block_type != 0xFFFF) + && (m_info_block_type != m_supported_info_block_type)) { + debugError("%s: Incorrect block type: 0x%04X, should be 0x%04X\n", + getInfoBlockName(), m_info_block_type, m_supported_info_block_type); + return false; + } + result &= se.write( m_compound_length, "AVCInfoBlock m_compound_length" ); + result &= se.write( m_info_block_type, "AVCInfoBlock m_info_block_type" ); + result &= se.write( m_primary_field_length, "AVCInfoBlock m_primary_field_length" ); + return result; +} + +bool +AVCInfoBlock::deserialize( IISDeserialize& de ) +{ + bool result=true; + result &= de.read( &m_compound_length ); + result &= de.read( &m_info_block_type ); + result &= de.read( &m_primary_field_length ); + + if((m_supported_info_block_type != 0xFFFF) + && (m_info_block_type != m_supported_info_block_type)) { + debugError("%s: Incorrect block type: 0x%04X, should be 0x%04X\n", + getInfoBlockName(), m_info_block_type, m_supported_info_block_type); + return false; + } + + debugOutput(DEBUG_LEVEL_VERBOSE, "%s length=0x%04X (%u), type=0x%04X, primary field length=0x%04X (%u)\n", + getInfoBlockName(), m_compound_length, m_compound_length, + m_info_block_type, m_primary_field_length, m_primary_field_length); + + return result; +} + +bool +AVCInfoBlock::peekBlockType( IISDeserialize& de, uint16_t *type ) +{ + return de.peek(type, 2); +} + +bool +AVCInfoBlock::peekBlockLength( IISDeserialize& de, uint16_t *type ) +{ + return de.peek(type, 0); +} + +AVCInfoBlock* +AVCInfoBlock::clone() const +{ + return new AVCInfoBlock( *this ); +} +bool +AVCInfoBlock::setVerbose( int verboseLevel ) +{ + setDebugLevel(verboseLevel); + return true; +} + +int +AVCInfoBlock::getVerboseLevel() +{ + return getDebugLevel(); +} + +// --------- + +//FIXME: find out the correct id for this +AVCRawTextInfoBlock::AVCRawTextInfoBlock( ) + : AVCInfoBlock( 0x000A ) +{} + +AVCRawTextInfoBlock::~AVCRawTextInfoBlock( ) +{ + clear(); +} + +bool +AVCRawTextInfoBlock::clear() +{ + return true; +} + +bool +AVCRawTextInfoBlock::serialize( IOSSerialize& se ) +{ + bool result=true; + result &= AVCInfoBlock::serialize(se); + if (m_text.size()) { + se.write(m_text.c_str(),m_text.size(), "AVCRawTextInfoBlock text"); + } + return result; +} + +bool +AVCRawTextInfoBlock::deserialize( IISDeserialize& de ) +{ + bool result=true; + result &= AVCInfoBlock::deserialize(de); + + char *txt; + result &= de.read(&txt,m_compound_length-4); + m_text.clear(); + m_text.append(txt); + + return result; +} + +// --------- + +AVCNameInfoBlock::AVCNameInfoBlock( ) + : AVCInfoBlock( 0x000B ) +{} + +AVCNameInfoBlock::~AVCNameInfoBlock( ) +{ + clear(); +} + +bool +AVCNameInfoBlock::clear() +{ + return true; +} + +bool +AVCNameInfoBlock::serialize( IOSSerialize& se ) +{ + bool result=true; + result &= AVCInfoBlock::serialize(se); + + if (m_text.size()) { + result &= se.write((uint16_t)0x0000, "AVCNameInfoBlock unknown"); + result &= se.write((uint16_t)0x0000, "AVCNameInfoBlock unknown"); + result &= se.write((uint16_t)0x0000, "AVCNameInfoBlock unknown length"); + result &= se.write((uint16_t)0x0000, "AVCNameInfoBlock unknown"); + result &= se.write((uint16_t)m_text.size(), "AVCNameInfoBlock text length"); + + se.write(m_text.c_str(),m_text.size(), "AVCNameInfoBlock text"); + } + return result; +} + +bool +AVCNameInfoBlock::deserialize( IISDeserialize& de ) +{ + bool result=true; + result &= AVCInfoBlock::deserialize(de); + + // FIXME: get the spec somewhere to do this correctly + uint16_t dummy16; + uint16_t length1; + uint16_t text_length; + + result &= de.read(&dummy16); + result &= de.read(&dummy16); + result &= de.read(&length1); + result &= de.read(&dummy16); + result &= de.read(&text_length); + + char *txt; + result &= de.read(&txt,text_length); + m_text.clear(); + m_text.append(txt); + + return result; +} + +} Index: trunk/libffado/src/libavc/descriptors/avc_descriptor_cmd.cpp =================================================================== --- trunk/libffado/src/libavc/descriptors/avc_descriptor_cmd.cpp (revision 503) +++ trunk/libffado/src/libavc/descriptors/avc_descriptor_cmd.cpp (revision 503) @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2007 by Pieter Palmers + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_descriptor_cmd.h" +#include "avc_descriptor.h" +#include "../util/avc_serialize.h" +#include "libieee1394/ieee1394service.h" + +#include +#include + +using namespace std; + +namespace AVC { + +OpenDescriptorCmd::OpenDescriptorCmd(Ieee1394Service& ieee1394service) + : AVCCommand( ieee1394service, AVC1394_CMD_OPEN_DESCRIPTOR ) + , m_specifier( NULL ) + , m_mode( eClose ) + , m_status ( 0xFF ) + , m_reserved ( 0x00 ) + , m_locked_node_id ( 0xFFFF ) +{ +} + +OpenDescriptorCmd::~OpenDescriptorCmd() +{ +} + +bool +OpenDescriptorCmd::clear() +{ + m_status = 0xFF; + m_reserved = 0x00; + m_locked_node_id = 0xFFFF; + return true; +} + +bool +OpenDescriptorCmd::serialize( IOSSerialize& se ) +{ + AVCCommand::serialize( se ); + + if(m_specifier==NULL) { + debugError("m_specifier==NULL"); + return false; + } + + m_specifier->serialize( se ); + + switch (getCommandType()) { + case eCT_Status: + se.write( (byte_t)m_status, "OpenDescriptorCmd status" ); + se.write( (byte_t)m_reserved, "OpenDescriptorCmd reserved" ); + se.write( (uint16_t)m_locked_node_id, "OpenDescriptorCmd node_id" ); + break; + case eCT_Control: + se.write( (byte_t)m_mode, "OpenDescriptorCmd subfunction" ); + se.write( (byte_t)m_reserved, "OpenDescriptorCmd reserved" ); + break; + default: + debugError("Unsupported type for this command: %02X\n", getCommandType()); + return false; + } + return true; +} + +bool +OpenDescriptorCmd::deserialize( IISDeserialize& de ) +{ + AVCCommand::deserialize( de ); + + if(m_specifier==NULL) { + debugError("m_specifier==NULL"); + return false; + } + + m_specifier->deserialize( de ); + + switch ( getCommandType() ) { + case eCT_Status: + de.read( &m_status ); + de.read( &m_reserved ); + de.read( &m_locked_node_id ); + + break; + case eCT_Control: + de.read( &m_status ); + de.read( &m_reserved ); + switch (m_status) { + case (byte_t)eClose: m_mode=eClose; break; + case (byte_t)eRead: m_mode=eRead; break; + case (byte_t)eWrite: m_mode=eWrite; break; + default: + debugError("Unknown response subfunction 0x%02X\n", m_status); + } + + break; + default: + debugError("Can't handle command type %s\n", getCommandType()); + return false; + } + + + return true; +} + +// + +ReadDescriptorCmd::ReadDescriptorCmd(Ieee1394Service& ieee1394service) + : AVCCommand( ieee1394service, AVC1394_CMD_READ_DESCRIPTOR ) + , m_status ( 0xFF ) + , m_reserved ( 0xFF ) + , m_data_length ( 0 ) + , m_address ( 0 ) + , m_data ( NULL ) + , m_specifier( NULL ) +{ +} + +ReadDescriptorCmd::~ReadDescriptorCmd() +{ + +} + +bool +ReadDescriptorCmd::clear() +{ + m_status = 0xFF; + m_reserved = 0x00; + m_data_length = 0x0000; + m_address = 0x0000; + return true; +} + +bool +ReadDescriptorCmd::serialize( IOSSerialize& se ) +{ + AVCCommand::serialize( se ); + + if(m_specifier==NULL) { + debugError("m_specifier==NULL"); + return false; + } + + m_specifier->serialize( se ); + + switch (getCommandType()) { + case eCT_Control: + se.write( (byte_t)m_status, "ReadDescriptorCmd read_result_status" ); + se.write( (byte_t)m_reserved, "ReadDescriptorCmd reserved" ); + se.write( (uint16_t)m_data_length, "ReadDescriptorCmd data_length" ); + se.write( (uint16_t)m_address, "ReadDescriptorCmd address" ); + + break; + default: + debugError("Unsupported type for this command: %02X\n", getCommandType()); + return false; + } + return true; + return true; +} + +bool +ReadDescriptorCmd::deserialize( IISDeserialize& de ) +{ + AVCCommand::deserialize( de ); + + if(m_specifier==NULL) { + debugError("m_specifier==NULL"); + return false; + } + + m_specifier->deserialize( de ); + + switch (getCommandType()) { + case eCT_Control: + de.read( (byte_t *)&m_status ); + de.read( (byte_t *)&m_reserved ); + de.read( (uint16_t *)&m_data_length ); + de.read( (uint16_t *)&m_address ); + + if (getResponse()==eR_Accepted) { + if (m_data_length>0) { + if (!de.read( (char **)&m_data, m_data_length )) { + m_data=NULL; + debugError("Could not read payload data"); + return false; + } + + } else { + debugWarning("Read descriptor command accepted but no payload data returned.\n"); + m_data=NULL; + } + } + break; + default: + debugError("Unsupported type for this command: %02X\n", getCommandType()); + return false; + } + + return true; +} + +enum ReadDescriptorCmd::EReadStatus +ReadDescriptorCmd::getStatus() +{ + switch(m_status) { + case 0x10: return eComplete; + case 0x11: return eMoreToRead; + case 0x12: return eTooLarge; + default: return eInvalid; + } +} + +} Index: trunk/libffado/src/libavc/descriptors/avc_descriptor.h =================================================================== --- trunk/libffado/src/libavc/descriptors/avc_descriptor.h (revision 524) +++ trunk/libffado/src/libavc/descriptors/avc_descriptor.h (revision 524) @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2007 by Pieter Palmers + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +/** + * Partially implements AV/C Descriptors/InfoBlocks as in TA2001021 + * + * The idea is to treat a descriptor as an object that can fetch and store + * it's state from/to a device. It will call the necessary AV/C commands to + * achieve this. This (hopefully) simplifies handling the fact that there are + * so many different descriptor types. It also handles the fact that descriptors + * are not state-less. + * + */ + +#ifndef AVCDESCRIPTOR_H +#define AVCDESCRIPTOR_H + +#include "../avc_definitions.h" + +#include "../general/avc_generic.h" +#include "debugmodule/debugmodule.h" + +#include +#include + +class Ieee1394Service; + +namespace AVC { + +class Unit; +class Subunit; + +class IOSSerialize; +class IISDeserialize; +/** + * The specifier used to indicate the target descriptor + */ + +// NOTE: how are we going to do this? all lengths of the +// arguments are dependent on the (sub)unit descriptor +class AVCDescriptorSpecifier : public IBusData +{ +public: + enum EType { + eIndentifier = 0x00, + eListById = 0x10, + eListByType = 0x11, + eEntryByListId = 0x20, + eEntryByObjectIdInList = 0x21, + eEntryByType = 0x22, + eEntryByObjectId = 0x23, + eInfoBlockByType = 0x30, + eInfoBlockByPosition = 0x31, + eSubunit0x80 = 0x80, + eInvalid = 0xFF, + }; + +public: + AVCDescriptorSpecifier( enum EType type ); + virtual ~AVCDescriptorSpecifier() {}; + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual AVCDescriptorSpecifier* clone() const; + +/* void setType( enum EType type ) {m_type=type;}; + void setListIdSize( unsigned int l ) {m_listid_size=l;}; + void setObjectIdSize( unsigned int l ) {m_objectid_size=l;}; + void setEntryPositionSize( unsigned int l ) {m_entrypos_size=l;};*/ + + enum EType m_type; + uint16_t m_listid_size; + uint16_t m_objectid_size; + uint16_t m_entrypos_size; + + uint16_t m_info_block_type; + byte_t m_info_block_instance; + byte_t m_info_block_position; + +private: + + +}; + +/** + * The descriptor class + */ +class AVCDescriptor : public IBusData +{ +public: + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + // note: in the end these have to be protected + AVCDescriptor( Unit* unit ); + AVCDescriptor( Unit* unit, Subunit* subunit ); + AVCDescriptor( Unit* unit, Subunit* subunit, AVCDescriptorSpecifier s ); + virtual ~AVCDescriptor(); + + virtual AVCDescriptor* clone() const; + + void setSpecifier(AVCDescriptorSpecifier s) {m_specifier=s;}; + + ESubunitType getSubunitType() const; + subunit_id_t getSubunitId() const; + + bool setVerboseLevel( int verboseLevel ); + int getVerboseLevel(); + + virtual const char* getDescriptorName() const + {return "AVCDescriptor";}; + + bool load(); + bool reload(); + +protected: + + Unit* m_unit; + Subunit* m_subunit; + + AVCDescriptorSpecifier m_specifier; + + byte_t* m_data; + uint16_t m_descriptor_length; + + bool m_loaded; + +}; + +/** + * The info block class + */ +class AVCInfoBlock : public IBusData +{ +public: + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + static bool peekBlockType( IISDeserialize& de, uint16_t * ); + static bool peekBlockLength( IISDeserialize& de, uint16_t * ); + + // note: in the end these have to be protected + AVCInfoBlock( ); + AVCInfoBlock( uint16_t ); + virtual ~AVCInfoBlock() {}; + + virtual AVCInfoBlock* clone() const; + +// EInfoBlockType getType(); + + bool setVerbose( int verboseLevel ); + int getVerboseLevel(); + + virtual const char* getInfoBlockName() const + {return "AVCInfoBlock";}; + + uint16_t m_compound_length; + uint16_t m_info_block_type; + uint16_t m_primary_field_length; + + uint16_t m_supported_info_block_type; +private: + +}; + +class AVCRawTextInfoBlock : public AVCInfoBlock +{ +public: + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual bool clear(); + + AVCRawTextInfoBlock( ); + virtual ~AVCRawTextInfoBlock(); + virtual const char* getInfoBlockName() const + {return "AVCRawTextInfoBlock";}; + + std::string m_text; + +protected: + +private: + +}; + +class AVCNameInfoBlock : public AVCInfoBlock +{ +public: + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual bool clear(); + + AVCNameInfoBlock( ); + virtual ~AVCNameInfoBlock(); + virtual const char* getInfoBlockName() const + {return "AVCNameInfoBlock";}; + + std::string m_text; + +protected: + +private: + +}; +/** + * + */ +// class AVCUnitIdentifierDescriptor : public AVCDescriptor +// { +// +// public: +// AVCUnitIdentifierDescriptor( ); +// virtual ~AVCUnitIdentifierDescriptor() {} +// +// }; + +} + +#endif // AVCDESCRIPTOR_H Index: trunk/libffado/src/libavc/ccm/avc_signal_source.cpp =================================================================== --- trunk/libffado/src/libavc/ccm/avc_signal_source.cpp (revision 505) +++ trunk/libffado/src/libavc/ccm/avc_signal_source.cpp (revision 505) @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_signal_source.h" +#include "../util/avc_serialize.h" +#include "libieee1394/ieee1394service.h" + +#include +#include + +using namespace std; + +#define AVC1394_CMD_SIGNAL_SOURCE 0x1A + +namespace AVC { + + +SignalUnitAddress::SignalUnitAddress() + : m_plugId( ePI_Invalid ) +{ +} + +bool +SignalUnitAddress::serialize( IOSSerialize& se ) +{ + byte_t reserved = 0xff; + se.write( reserved, "SignalUnitAddress" ); + se.write( m_plugId, "SignalUnitAddress plugId" ); + return true; +} + +bool +SignalUnitAddress::deserialize( IISDeserialize& de ) +{ + byte_t operand; + de.read( &operand ); + de.read( &m_plugId ); + return true; +} + +SignalUnitAddress* +SignalUnitAddress::clone() const +{ + return new SignalUnitAddress( *this ); +} + +//////////////////////////////////////// + +SignalSubunitAddress::SignalSubunitAddress() + : m_subunitType( AVC1394_SUBUNIT_RESERVED ) + , m_subunitId( AVC1394_SUBUNIT_ID_RESERVED ) + , m_plugId( ePI_Invalid ) +{ +} + +bool +SignalSubunitAddress::serialize( IOSSerialize& se ) +{ + byte_t operand = ( m_subunitType << 3 ) | ( m_subunitId & 0x7 ); + se.write( operand, "SignalSubunitAddress subunitType & subunitId" ); + se.write( m_plugId, "SignalSubunitAddress plugId" ); + return true; +} + +bool +SignalSubunitAddress::deserialize( IISDeserialize& de ) +{ + byte_t operand; + de.read( &operand ); + m_subunitType = operand >> 3; + m_subunitId = operand & 0x7; + de.read( &m_plugId ); + return true; +} + +SignalSubunitAddress* +SignalSubunitAddress::clone() const +{ + return new SignalSubunitAddress( *this ); +} + +//////////////////////////////////////// + + +SignalSourceCmd::SignalSourceCmd( Ieee1394Service& ieee1394service ) + : AVCCommand( ieee1394service, AVC1394_CMD_SIGNAL_SOURCE ) + , m_resultStatus( 0xff ) + , m_outputStatus( 0xff ) + , m_conv( 0xff ) + , m_signalStatus( 0xff ) + , m_signalSource( 0 ) + , m_signalDestination( 0 ) +{ +} + +SignalSourceCmd::~SignalSourceCmd() +{ + delete m_signalSource; + m_signalSource = 0; + delete m_signalDestination; + m_signalDestination = 0; +} + +bool +SignalSourceCmd::serialize( IOSSerialize& se ) +{ + AVCCommand::serialize( se ); + + byte_t operand; + switch ( getCommandType() ) { + case eCT_Status: + operand = ( m_outputStatus << 5 ) + | ( ( m_conv & 0x1 ) << 4 ) + | ( m_signalStatus & 0xf ); + se.write( operand, "SignalSourceCmd outputStatus & conv & signalStatus" ); + break; + case eCT_Control: + case eCT_SpecificInquiry: + operand = m_resultStatus & 0xf; + se.write( operand, "SignalSourceCmd resultStatus" ); + break; + default: + cerr << "Can't handle command type " << getCommandType() << endl; + return false; + } + + switch( getSubunitType() ) { + case eST_Unit: + case eST_Audio: + case eST_Music: + { + if ( m_signalSource ) { + m_signalSource->serialize( se ); + } else { + byte_t reserved = 0xff; + se.write( reserved, "SignalSourceCmd" ); + se.write( reserved, "SignalSourceCmd" ); + } + + if ( m_signalDestination ) { + m_signalDestination->serialize( se ); + } else { + byte_t reserved = 0xff; + se.write( reserved, "SignalSourceCmd" ); + se.write( reserved, "SignalSourceCmd" ); + } + } + break; + default: + cerr << "Can't handle subunit type " << getSubunitType() << endl; + return false; + } + + return true; +} + +bool +SignalSourceCmd::deserialize( IISDeserialize& de ) +{ + delete m_signalSource; + m_signalSource = 0; + delete m_signalDestination; + m_signalDestination = 0; + + AVCCommand::deserialize( de ); + + byte_t operand; + switch ( getCommandType() ) { + case eCT_Status: + de.read( &operand ); + m_outputStatus = operand >> 5; + m_conv = ( operand & 0x10 ) >> 4; + m_signalStatus = operand & 0xf; + break; + case eCT_Control: + case eCT_SpecificInquiry: + de.read( &operand ); + m_resultStatus = operand & 0xf; + break; + default: + cerr << "Can't handle command type " << getCommandType() << endl; + return false; + } + + switch( getSubunitType() ) { + case eST_Unit: + case eST_Audio: + case eST_Music: + { + byte_t operand; + de.peek( &operand ); + if ( operand == 0xff ) { + m_signalSource = new SignalUnitAddress; + } else { + m_signalSource = new SignalSubunitAddress; + } + + m_signalSource->deserialize( de ); + + de.peek( &operand ); + if ( operand == 0xff ) { + m_signalDestination = new SignalUnitAddress; + } else { + m_signalDestination = new SignalSubunitAddress; + } + m_signalDestination->deserialize( de ); + } + break; + default: + cerr << "Can't handle subunit type " << getSubunitType() << endl; + return false; + } + + return true; +} + +bool +SignalSourceCmd::setSignalSource( SignalUnitAddress& signalAddress ) +{ + if ( m_signalSource ) { + delete m_signalSource; + } + m_signalSource = signalAddress.clone(); + return true; +} + +bool +SignalSourceCmd::setSignalSource( SignalSubunitAddress& signalAddress ) +{ + if ( m_signalSource ) { + delete m_signalSource; + } + m_signalSource = signalAddress.clone(); + return true; +} + +bool +SignalSourceCmd::setSignalDestination( SignalUnitAddress& signalAddress ) +{ + if ( m_signalDestination ) { + delete m_signalDestination; + } + m_signalDestination = signalAddress.clone(); + return true; +} + +bool +SignalSourceCmd::setSignalDestination( SignalSubunitAddress& signalAddress ) +{ + if ( m_signalDestination ) { + delete m_signalDestination; + } + m_signalDestination = signalAddress.clone(); + return true; +} + +SignalAddress* +SignalSourceCmd::getSignalSource() +{ + return m_signalSource; +} + +SignalAddress* +SignalSourceCmd::getSignalDestination() +{ + return m_signalDestination; +} + +} Index: trunk/libffado/src/libavc/ccm/avc_signal_source.h =================================================================== --- trunk/libffado/src/libavc/ccm/avc_signal_source.h (revision 503) +++ trunk/libffado/src/libavc/ccm/avc_signal_source.h (revision 503) @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVCSIGNALSOURCE_H +#define AVCSIGNALSOURCE_H + +#include "../general/avc_generic.h" +#include "../avc_definitions.h" + +#include + +namespace AVC { + + +class SignalAddress: public IBusData +{ +public: + enum EPlugId { + ePI_AnyAvailableSerialBusPlug = 0x7e, + ePI_Invalid = 0xfe, + ePI_AnyAvailableExternalPlug = 0xff, + }; +}; + +class SignalUnitAddress: public SignalAddress +{ +public: + SignalUnitAddress(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual SignalUnitAddress* clone() const; + + byte_t m_plugId; +}; + +class SignalSubunitAddress: public SignalAddress +{ +public: + SignalSubunitAddress(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual SignalSubunitAddress* clone() const; + + byte_t m_subunitType; + byte_t m_subunitId; + byte_t m_plugId; +}; + +class SignalSourceCmd: public AVCCommand +{ +public: + SignalSourceCmd( Ieee1394Service& ieee1394service ); + virtual ~SignalSourceCmd(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual const char* getCmdName() const + { return "SignalSourceCmd"; } + + bool setSignalSource( SignalUnitAddress& signalAddress ); + bool setSignalSource( SignalSubunitAddress& signalAddress ); + bool setSignalDestination( SignalUnitAddress& signalAddress ); + bool setSignalDestination( SignalSubunitAddress& signalAddress ); + + SignalAddress* getSignalSource(); + SignalAddress* getSignalDestination(); + + // Control response + byte_t m_resultStatus; + + // Status response + byte_t m_outputStatus; + byte_t m_conv; + byte_t m_signalStatus; + + SignalAddress* m_signalSource; + SignalAddress* m_signalDestination; +}; + +} + +#endif // AVCSIGNALSOURCE_H Index: trunk/libffado/src/libavc/streamformat/avc_extended_stream_format.h =================================================================== --- trunk/libffado/src/libavc/streamformat/avc_extended_stream_format.h (revision 503) +++ trunk/libffado/src/libavc/streamformat/avc_extended_stream_format.h (revision 503) @@ -0,0 +1,293 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVCEXTENDEDSTREAMFROMAT_H +#define AVCEXTENDEDSTREAMFROMAT_H + +#include "../general/avc_generic.h" +#include "../general/avc_extended_cmd_generic.h" + +#include +#include +#include + +namespace AVC { + +#define AVC1394_STREAM_FORMAT_SUPPORT 0x2F +#define AVC1394_STREAM_FORMAT_SUBFUNCTION_INPUT 0x00 +#define AVC1394_STREAM_FORMAT_SUBFUNCTION_OUTPUT 0x01 + +// BridgeCo extensions +#define AVC1394_STREAM_FORMAT_SUBFUNCTION_EXTENDED_STREAM_FORMAT 0xC0 +#define AVC1394_STREAM_FORMAT_SUBFUNCTION_EXTENDED_STREAM_FORMAT_LIST 0xC1 + + +#define AVC1394_STREAM_FORMAT_HIERARCHY_ROOT_DVCR 0x80 +#define AVC1394_STREAM_FORMAT_HIERARCHY_ROOT_AUDIOMUSIC 0x90 +#define AVC1394_STREAM_FORMAT_HIERARCHY_ROOT_INVALID 0xFF + +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_SD525_60 0x00 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_SDL525_60 0x04 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_HD1125_60 0x08 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_SD625_60 0x80 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_SDL625_50 0x84 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_HD1250_50 0x88 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_AM824 0x00 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_24_4_AUDIO_PACK 0x01 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_32_FLOATING_POINT_DATA 0x02 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_AM824_COMPOUND 0x40 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_DONT_CARE 0xFF + + +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC60968_3 0x00 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_3 0x01 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_4 0x02 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_5 0x03 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_6 0x04 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_7 0x05 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_MULTI_BIT_LINEAR_AUDIO_RAW 0x06 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_MULTI_BIT_LINEAR_AUDIO_DVD_AUDIO 0x07 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_ONE_BIT_AUDIO_PLAIN_RAW 0x08 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_ONE_BIT_AUDIO_PLAIN_SACD 0x09 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_ONE_BIT_AUDIO_ENCODED_RAW 0x0A +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_ONE_BIT_AUDIO_ENCODED_SACD 0x0B +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_HIGH_PRECISION_MULTIBIT_LINEAR_AUDIO 0x0C +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_MIDI_CONFORMANT 0x0D +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_SYNC_STREAM 0x40 +#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_DONT_CARE 0xFF + +#define AVC1394_STREAM_FORMAT_AM824_IEC60968_3 0x00 +#define AVC1394_STREAM_FORMAT_AM824_IEC61937_3 0x01 +#define AVC1394_STREAM_FORMAT_AM824_IEC61937_4 0x02 +#define AVC1394_STREAM_FORMAT_AM824_IEC61937_5 0x03 +#define AVC1394_STREAM_FORMAT_AM824_IEC61937_6 0x04 +#define AVC1394_STREAM_FORMAT_AM824_IEC61937_7 0x05 +#define AVC1394_STREAM_FORMAT_AM824_MULTI_BIT_LINEAR_AUDIO_RAW 0x06 +#define AVC1394_STREAM_FORMAT_AM824_MULTI_BIT_LINEAR_AUDIO_DVD_AUDIO 0x07 +#define AVC1394_STREAM_FORMAT_AM824_HIGH_PRECISION_MULTIBIT_LINEAR_AUDIO 0x0C +#define AVC1394_STREAM_FORMAT_AM824_MIDI_CONFORMANT 0x0D +#define AVC1394_STREAM_FORMAT_AM824_DONT_CARE 0xFF + +/* +// As defined in 'AV/C Stream Format Information Specification 1.0 TA Document 2001002' +// Not used for extended stream format +#define AVC1394_STREAM_FORMAT_SUPPORT_STATUS_SUPPORTED_AND_CONFIGURED 0x00 +#define AVC1394_STREAM_FORMAT_SUPPORT_STATUS_SUPPORTED_AND_HAS_NOT_BEEN_CONFIGURED 0x01 +#define AVC1394_STREAM_FORMAT_SUPPORT_STATUS_SUPPORTED_AND_READY_TO_CONFIGURE 0x02 +#define AVC1394_STREAM_FORMAT_SUPPORT_STATUS_SUPPORTED_AND_NOT_CONFIGURED 0x03 +#define AVC1394_STREAM_FORMAT_SUPPORT_STATUS_NOT_SUPPORTED 0x04 +// 0x05 - 0xFE reserved +#define AVC1394_STREAM_FORMAT_SUPPORT_STATUS_NO_INFORMATION 0xFF +*/ + +#define AVC1394_EXTENDED_STREAM_FORMAT_INFO_STATUS_ACTIVE 0x00 +#define AVC1394_EXTENDED_STREAM_FORMAT_INFO_STATUS_INACTIVE 0x01 +#define AVC1394_EXTENDED_STREAM_FORMAT_INFO_STATUS_NO_STREAM_FORMAT 0x02 +#define AVC1394_EXTENDED_STREAM_FORMAT_INFO_STATUS_NOT_USED 0xff + +class IOSSerialize; +class IISDeserialize; + +enum ERateControl { + eRC_Supported = 0x00, + eRC_DontCare = 0x01, +}; + +//////////////////////////////////////////////////////////// + +class StreamFormatInfo: public IBusData +{ +public: + StreamFormatInfo(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual StreamFormatInfo* clone() const; + + number_of_channels_t m_numberOfChannels; + stream_format_t m_streamFormat; +}; +std::ostream& operator<<( std::ostream& stream, StreamFormatInfo info ); + +//////////////////////////////////////////////////////////// + +class FormatInformationStreams: public IBusData +{ +public: + FormatInformationStreams() {} + virtual ~FormatInformationStreams() {} +}; + +//////////////////////////////////////////////////////////// + +class FormatInformationStreamsSync: public FormatInformationStreams +{ +public: + FormatInformationStreamsSync(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual FormatInformationStreamsSync* clone() const; + + reserved_t m_reserved0; + sampling_frequency_t m_samplingFrequency; + rate_control_t m_rateControl; + reserved_t m_reserved1; +}; + +//////////////////////////////////////////////////////////// + +class FormatInformationStreamsCompound: public FormatInformationStreams +{ +public: + FormatInformationStreamsCompound(); + virtual ~FormatInformationStreamsCompound(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual FormatInformationStreamsCompound* clone() const; + + sampling_frequency_t m_samplingFrequency; + rate_control_t m_rateControl; + number_of_stream_format_infos_t m_numberOfStreamFormatInfos; + + typedef std::vector< StreamFormatInfo* > StreamFormatInfoVector; + StreamFormatInfoVector m_streamFormatInfos; +}; +std::ostream& operator<<( std::ostream& stream, FormatInformationStreamsCompound info ); + + +//////////////////////////////////////////////////////////// + +class FormatInformation: public IBusData +{ +public: + enum EFormatHierarchyRoot { + eFHR_DVCR = AVC1394_STREAM_FORMAT_HIERARCHY_ROOT_DVCR, + eFHR_AudioMusic = AVC1394_STREAM_FORMAT_HIERARCHY_ROOT_AUDIOMUSIC, + eFHR_Invalid = AVC1394_STREAM_FORMAT_HIERARCHY_ROOT_INVALID, + }; + + enum EFomatHierarchyLevel1 { + eFHL1_DVCR_SD525_60 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_SD525_60, + eFHL1_DVCR_SDL525_60 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_SDL525_60, + eFHL1_DVCR_HD1125_60 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_HD1125_60, + eFHL1_DVCR_SD625_60 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_SD625_60, + eFHL1_DVCR_SDL625_50 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_SDL625_50, + eFHL1_DVCR_HD1250_50 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_HD1250_50, + eFHL1_AUDIOMUSIC_AM824 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_AM824, + eFHL1_AUDIOMUSIC_24_4_AUDIO_PACK = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_24_4_AUDIO_PACK, + eFHL1_AUDIOMUSIC_32_FLOATING = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_32_FLOATING_POINT_DATA, + eFHL1_AUDIOMUSIC_AM824_COMPOUND = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_AM824_COMPOUND, + eFHL1_AUDIOMUSIC_DONT_CARE = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_DONT_CARE, + }; + + enum EFormatHierarchyLevel2 { + eFHL2_AM824_IEC60968_3 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC60968_3, + eFHL2_AM824_IEC61937_3 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_3, + eFHL2_AM824_IEC61937_4 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_4, + eFHL2_AM824_IEC61937_5 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_5, + eFHL2_AM824_IEC61937_6 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_6, + eFHL2_AM824_IEC61937_7 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_7, + eFHL2_AM824_MULTI_BIT_LINEAR_AUDIO_RAW = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_MULTI_BIT_LINEAR_AUDIO_RAW, + eFHL2_AM824_MULTI_BIT_LINEAR_AUDIO_DVD_AUDIO = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_MULTI_BIT_LINEAR_AUDIO_DVD_AUDIO, + eFHL2_AM824_ONE_BIT_AUDIO_PLAIN_RAW = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_ONE_BIT_AUDIO_PLAIN_RAW, + eFHL2_AM824_ONE_BIT_AUDIO_PLAIN_SACD = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_ONE_BIT_AUDIO_PLAIN_SACD, + eFHL2_AM824_ONE_BIT_AUDIO_ENCODED_RAW = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_ONE_BIT_AUDIO_ENCODED_RAW, + eFHL2_AM824_ONE_BIT_AUDIO_ENCODED_SACD = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_ONE_BIT_AUDIO_ENCODED_SACD, + eFHL2_AM824_HIGH_PRECISION_MULTIBIT_LINEAR_AUDIO = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_HIGH_PRECISION_MULTIBIT_LINEAR_AUDIO, + eFHL2_AM824_MIDI_CONFORMANT = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_MIDI_CONFORMANT, + eFHL2_AM824_SYNC_STREAM = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_SYNC_STREAM, + eFHL2_AM824_DONT_CARE = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_DONT_CARE, + }; + + typedef byte_t format_hierarchy_root_t; + typedef byte_t format_hierarchy_level1_t; + typedef byte_t format_hierarchy_level2_t; + + FormatInformation(); + FormatInformation( const FormatInformation& rhs ); + virtual ~FormatInformation(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual FormatInformation* clone() const; + + format_hierarchy_root_t m_root; + format_hierarchy_level1_t m_level1; + format_hierarchy_level2_t m_level2; + FormatInformationStreams* m_streams; +}; + +/////////////////////////////////////////////////////////// + +class ExtendedStreamFormatCmd: public AVCCommand +{ +public: + enum ESubFunction { + eSF_Input = AVC1394_STREAM_FORMAT_SUBFUNCTION_INPUT, + eSF_Output = AVC1394_STREAM_FORMAT_SUBFUNCTION_OUTPUT, + eSF_ExtendedStreamFormatInformationCommand = AVC1394_STREAM_FORMAT_SUBFUNCTION_EXTENDED_STREAM_FORMAT, + eSF_ExtendedStreamFormatInformationCommandList = AVC1394_STREAM_FORMAT_SUBFUNCTION_EXTENDED_STREAM_FORMAT_LIST, + }; + + enum EStatus { + eS_Active = AVC1394_EXTENDED_STREAM_FORMAT_INFO_STATUS_ACTIVE, + eS_Inactive = AVC1394_EXTENDED_STREAM_FORMAT_INFO_STATUS_INACTIVE, + eS_NoStreamFormat = AVC1394_EXTENDED_STREAM_FORMAT_INFO_STATUS_NO_STREAM_FORMAT, + eS_NotUsed = AVC1394_EXTENDED_STREAM_FORMAT_INFO_STATUS_NOT_USED, + }; + typedef byte_t status_t; + typedef byte_t index_in_stream_format_t; + + ExtendedStreamFormatCmd( Ieee1394Service& ieee1349service, ESubFunction eSubFunction = eSF_ExtendedStreamFormatInformationCommand ); + ExtendedStreamFormatCmd( const ExtendedStreamFormatCmd& rhs ); + virtual ~ExtendedStreamFormatCmd(); + + bool setPlugAddress( const PlugAddress& plugAddress ); + bool setIndexInStreamFormat( const int index ); + bool setSubFunction( ESubFunction subFunction ); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + EStatus getStatus(); + FormatInformation* getFormatInformation(); + index_in_stream_format_t getIndex(); + + virtual const char* getCmdName() const + { return "ExtendedStreamFormatCmd"; } + +protected: + subfunction_t m_subFunction; + PlugAddress* m_plugAddress; + status_t m_status; + index_in_stream_format_t m_indexInStreamFormat; + FormatInformation* m_formatInformation; +}; + +} + +#endif // AVCEXTENDEDSTREAMFROMAT_H Index: trunk/libffado/src/libavc/streamformat/avc_extended_stream_format.cpp =================================================================== --- trunk/libffado/src/libavc/streamformat/avc_extended_stream_format.cpp (revision 505) +++ trunk/libffado/src/libavc/streamformat/avc_extended_stream_format.cpp (revision 505) @@ -0,0 +1,393 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_extended_stream_format.h" +#include "../util/avc_serialize.h" +#include "libieee1394/ieee1394service.h" + +#include + +namespace AVC { + +/////////////////////////////////////////////////////////// +std::ostream& operator<<( std::ostream& stream, StreamFormatInfo info ) +{ +/* stream << info.m_freq << " Hz ("; + if ( info.m_format ) { + stream << "sync "; + } else { + stream << "compound "; + } + stream << "stream, "; + stream << "audio channels: " << info.m_audioChannels + << ", midi channels: " << info.m_midiChannels << ")"; +*/ + stream << " NbChannels " << (int)info.m_numberOfChannels << ", Format " << (int)info.m_streamFormat; + return stream; +} + +StreamFormatInfo::StreamFormatInfo() + : IBusData() +{ +} + +bool +StreamFormatInfo::serialize( IOSSerialize& se ) +{ + se.write( m_numberOfChannels, "StreamFormatInfo numberOfChannels" ); + se.write( m_streamFormat, "StreamFormatInfo streamFormat" ); + return true; +} + +bool +StreamFormatInfo::deserialize( IISDeserialize& de ) +{ + de.read( &m_numberOfChannels ); + de.read( &m_streamFormat ); + return true; +} + +StreamFormatInfo* +StreamFormatInfo::clone() const +{ + return new StreamFormatInfo( *this ); +} + +//////////////////////////////////////////////////////////// + +FormatInformationStreamsSync::FormatInformationStreamsSync() + : FormatInformationStreams() + , m_reserved0( 0xff ) + , m_samplingFrequency( eSF_DontCare ) + , m_rateControl( eRC_DontCare ) + , m_reserved1( 0xff ) +{ +} + +bool +FormatInformationStreamsSync::serialize( IOSSerialize& se ) +{ + se.write( m_reserved0, "FormatInformationStreamsSync reserved" ); + + // we have to clobber some bits + byte_t operand = ( m_samplingFrequency << 4 ) | 0x0e; + if ( m_rateControl == eRC_DontCare) { + operand |= 0x1; + } + se.write( operand, "FormatInformationStreamsSync sampling frequency and rate control" ); + + se.write( m_reserved1, "FormatInformationStreamsSync reserved" ); + return true; +} + +bool +FormatInformationStreamsSync::deserialize( IISDeserialize& de ) +{ + de.read( &m_reserved0 ); + + byte_t operand; + de.read( &operand ); + m_samplingFrequency = operand >> 4; + m_rateControl = operand & 0x01; + + de.read( &m_reserved1 ); + return true; +} + +FormatInformationStreamsSync* +FormatInformationStreamsSync::clone() const +{ + return new FormatInformationStreamsSync( *this ); +} + +//////////////////////////////////////////////////////////// +std::ostream& operator<<( std::ostream& stream, FormatInformationStreamsCompound info ) +{ + stream << (int)info.m_samplingFrequency << " Hz (rate control: "; + stream << (int)info.m_rateControl << ")" << std::endl; + + for ( FormatInformationStreamsCompound::StreamFormatInfoVector::iterator it = info.m_streamFormatInfos.begin(); + it != info.m_streamFormatInfos.end(); + ++it ) + { + StreamFormatInfo* sfi=*it; + stream << " > " << *sfi << std::endl; + } + + return stream; +} + +FormatInformationStreamsCompound::FormatInformationStreamsCompound() + : FormatInformationStreams() + , m_samplingFrequency( eSF_DontCare ) + , m_rateControl( eRC_DontCare ) + , m_numberOfStreamFormatInfos( 0 ) +{ +} + +FormatInformationStreamsCompound::~FormatInformationStreamsCompound() +{ + for ( StreamFormatInfoVector::iterator it = m_streamFormatInfos.begin(); + it != m_streamFormatInfos.end(); + ++it ) + { + delete *it; + } +} + +bool +FormatInformationStreamsCompound::serialize( IOSSerialize& se ) +{ + se.write( m_samplingFrequency, "FormatInformationStreamsCompound samplingFrequency" ); + se.write( m_rateControl, "FormatInformationStreamsCompound rateControl" ); + se.write( m_numberOfStreamFormatInfos, "FormatInformationStreamsCompound numberOfStreamFormatInfos" ); + for ( StreamFormatInfoVector::iterator it = m_streamFormatInfos.begin(); + it != m_streamFormatInfos.end(); + ++it ) + { + ( *it )->serialize( se ); + } + return true; +} + +bool +FormatInformationStreamsCompound::deserialize( IISDeserialize& de ) +{ + de.read( &m_samplingFrequency ); + de.read( &m_rateControl ); + de.read( &m_numberOfStreamFormatInfos ); + for ( int i = 0; i < m_numberOfStreamFormatInfos; ++i ) { + StreamFormatInfo* streamFormatInfo = new StreamFormatInfo; + if ( !streamFormatInfo->deserialize( de ) ) { + return false; + } + m_streamFormatInfos.push_back( streamFormatInfo ); + } + return true; +} + +FormatInformationStreamsCompound* +FormatInformationStreamsCompound::clone() const +{ + return new FormatInformationStreamsCompound( *this ); +} + +//////////////////////////////////////////////////////////// + +FormatInformation::FormatInformation() + : IBusData() + , m_root( eFHR_Invalid ) + , m_level1( eFHL1_AUDIOMUSIC_DONT_CARE ) + , m_level2( eFHL2_AM824_DONT_CARE ) + , m_streams( 0 ) +{ +} + +FormatInformation::FormatInformation( const FormatInformation& rhs ) + : IBusData() + , m_root( rhs.m_root ) + , m_level1( rhs.m_level1 ) + , m_level2( rhs.m_level2 ) + , m_streams( 0 ) +{ + if ( rhs.m_streams ) { + m_streams = dynamic_cast( rhs.m_streams->clone() ); + } +} + +FormatInformation::~FormatInformation() +{ + delete m_streams; + m_streams = 0; +} + +bool +FormatInformation::serialize( IOSSerialize& se ) +{ + if ( m_root != eFHR_Invalid ) { + se.write( m_root, "FormatInformation hierarchy root" ); + if ( m_level1 != eFHL1_AUDIOMUSIC_DONT_CARE ) { + se.write( m_level1, "FormatInformation hierarchy level 1" ); + if ( m_level2 != eFHL2_AM824_DONT_CARE ) { + se.write( m_level2, "FormatInformation hierarchy level 2" ); + } + } + } + if ( m_streams ) { + return m_streams->serialize( se ); + } + return true; +} + +bool +FormatInformation::deserialize( IISDeserialize& de ) +{ + bool result = false; + + delete m_streams; + m_streams = 0; + + // this code just parses BeBoB replies. + de.read( &m_root ); + + // just parse an audio and music hierarchy + if ( m_root == eFHR_AudioMusic ) { + de.read( &m_level1 ); + + switch ( m_level1 ) { + case eFHL1_AUDIOMUSIC_AM824: + { + // note: compound streams don't have a second level + de.read( &m_level2 ); + + if (m_level2 == eFHL2_AM824_SYNC_STREAM ) { + m_streams = new FormatInformationStreamsSync(); + result = m_streams->deserialize( de ); + } else { + // anything but the sync stream workds currently. + printf( "could not parse format information. (format hierarchy level 2 not recognized)\n" ); + } + } + break; + case eFHL1_AUDIOMUSIC_AM824_COMPOUND: + { + m_streams = new FormatInformationStreamsCompound(); + result = m_streams->deserialize( de ); + } + break; + default: + printf( "could not parse format information. (format hierarchy level 1 not recognized)\n" ); + } + } + + return result; +} + +FormatInformation* +FormatInformation::clone() const +{ + return new FormatInformation( *this ); +} + +//////////////////////////////////////////////////////////// + +ExtendedStreamFormatCmd::ExtendedStreamFormatCmd( Ieee1394Service& service, + ESubFunction eSubFunction ) + : AVCCommand( service, AVC1394_STREAM_FORMAT_SUPPORT ) + , m_subFunction( eSubFunction ) + , m_status( eS_NotUsed ) + , m_indexInStreamFormat( 0 ) + , m_formatInformation( new FormatInformation ) +{ + UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, 0x00 ); + m_plugAddress = new PlugAddress( PlugAddress::ePD_Output, PlugAddress::ePAM_Unit, unitPlugAddress ); +} + +ExtendedStreamFormatCmd::ExtendedStreamFormatCmd( + const ExtendedStreamFormatCmd& rhs ) + : AVCCommand( rhs ) +{ + m_subFunction = rhs.m_subFunction; + m_plugAddress = new PlugAddress( *rhs.m_plugAddress ); + m_formatInformation = + new FormatInformation( *rhs.m_formatInformation ); +} + +ExtendedStreamFormatCmd::~ExtendedStreamFormatCmd() +{ + delete m_plugAddress; + m_plugAddress = 0; + delete m_formatInformation; + m_formatInformation = 0; +} + +bool +ExtendedStreamFormatCmd::setPlugAddress( const PlugAddress& plugAddress ) +{ + delete m_plugAddress; + m_plugAddress = plugAddress.clone(); + return true; +} + +bool +ExtendedStreamFormatCmd::setIndexInStreamFormat( const int index ) +{ + m_indexInStreamFormat = index; + return true; +} + +bool +ExtendedStreamFormatCmd::serialize( IOSSerialize& se ) +{ + AVCCommand::serialize( se ); + se.write( m_subFunction, "ExtendedStreamFormatCmd subFunction" ); + m_plugAddress->serialize( se ); + se.write( m_status, "ExtendedStreamFormatCmd status" ); + if ( m_subFunction == eSF_ExtendedStreamFormatInformationCommandList ) { + se.write( m_indexInStreamFormat, "indexInStreamFormat" ); + } + m_formatInformation->serialize( se ); + return true; +} + +bool +ExtendedStreamFormatCmd::deserialize( IISDeserialize& de ) +{ + AVCCommand::deserialize( de ); + de.read( &m_subFunction ); + m_plugAddress->deserialize( de ); + de.read( &m_status ); + if ( m_subFunction == eSF_ExtendedStreamFormatInformationCommandList ) { + de.read( &m_indexInStreamFormat ); + } + m_formatInformation->deserialize( de ); + return true; +} + +ExtendedStreamFormatCmd::EStatus +ExtendedStreamFormatCmd::getStatus() +{ + EStatus status = static_cast( m_status ); + return status; +} + +FormatInformation* +ExtendedStreamFormatCmd::getFormatInformation() +{ + return m_formatInformation; +} + +ExtendedStreamFormatCmd::index_in_stream_format_t +ExtendedStreamFormatCmd::getIndex() +{ + return m_indexInStreamFormat; +} + +bool +ExtendedStreamFormatCmd::setSubFunction( ESubFunction subFunction ) +{ + m_subFunction = subFunction; + return true; +} + +} Index: trunk/libffado/src/libavc/avc_definitions.cpp =================================================================== --- trunk/libffado/src/libavc/avc_definitions.cpp (revision 445) +++ trunk/libffado/src/libavc/avc_definitions.cpp (revision 554) @@ -23,5 +23,7 @@ #include "avc_definitions.h" - +#include + +namespace AVC { int @@ -151,2 +153,68 @@ return stream << str; }; + +enum ESubunitType byteToSubunitType(byte_t s) { + switch (s) { + case eST_Monitor: + return eST_Monitor; + case eST_Audio: + return eST_Audio; + case eST_Printer: + return eST_Printer; + case eST_Disc: + return eST_Disc; + case eST_VCR: + return eST_VCR; + case eST_Tuner: + return eST_Tuner; + case eST_CA: + return eST_CA; + case eST_Camera: + return eST_Camera; + case eST_Panel: + return eST_Panel; + case eST_BulltinBoard: + return eST_BulltinBoard; + case eST_CameraStorage: + return eST_CameraStorage; + case eST_Music: + return eST_Music; + case eST_VendorUnique: + return eST_VendorUnique; + case eST_Reserved: + return eST_Reserved; + case eST_Extended: + return eST_Extended; + default: + case eST_Unit: + return eST_Unit; + } +} + +unsigned int fdfSfcToSampleRate(byte_t fdf) { + switch(fdf & 0x07) { + default: return 0; + case IEC61883_FDF_SFC_32KHZ: return 32000; + case IEC61883_FDF_SFC_44K1HZ: return 44100; + case IEC61883_FDF_SFC_48KHZ: return 48000; + case IEC61883_FDF_SFC_88K2HZ: return 88200; + case IEC61883_FDF_SFC_96KHZ: return 96000; + case IEC61883_FDF_SFC_176K4HZ: return 176400; + case IEC61883_FDF_SFC_192KHZ: return 192000; + } +} + +byte_t sampleRateToFdfSfc(unsigned int rate) { + switch(rate) { + default: return 0x07; + case 32000: return IEC61883_FDF_SFC_32KHZ; + case 44100: return IEC61883_FDF_SFC_44K1HZ; + case 48000: return IEC61883_FDF_SFC_48KHZ; + case 88200: return IEC61883_FDF_SFC_88K2HZ; + case 96000: return IEC61883_FDF_SFC_96KHZ; + case 176400: return IEC61883_FDF_SFC_176K4HZ; + case 192000: return IEC61883_FDF_SFC_192KHZ; + } +} + +} Index: trunk/libffado/src/libavc/avc_definitions.h =================================================================== --- trunk/libffado/src/libavc/avc_definitions.h (revision 445) +++ trunk/libffado/src/libavc/avc_definitions.h (revision 554) @@ -22,9 +22,12 @@ */ -#ifndef AVDDEFINITIONS_H -#define AVDDEFINITIONS_H +#ifndef AVCDEFINITIONS_H +#define AVCDEFINITIONS_H #include #include + + +namespace AVC { typedef byte_t ctype_t; @@ -83,4 +86,36 @@ typedef quadlet_t company_id_t; +#define AVC1394_SUBUNIT_AUDIO 1 +#define AVC1394_SUBUNIT_PRINTER 2 +#define AVC1394_SUBUNIT_CA 6 +#define AVC1394_SUBUNIT_PANEL 9 +#define AVC1394_SUBUNIT_BULLETIN_BOARD 0xA +#define AVC1394_SUBUNIT_CAMERA_STORAGE 0xB +#define AVC1394_SUBUNIT_MUSIC 0xC +#define AVC1394_SUBUNIT_RESERVED 0x1D + +#define AVC1394_SUBUNIT_ID_RESERVED 0x06 + +enum ESubunitType { + eST_Monitor = AVC1394_SUBUNIT_VIDEO_MONITOR, + eST_Audio = AVC1394_SUBUNIT_AUDIO, + eST_Printer = AVC1394_SUBUNIT_PRINTER, + eST_Disc = AVC1394_SUBUNIT_DISC_RECORDER, + eST_VCR = AVC1394_SUBUNIT_VCR, + eST_Tuner = AVC1394_SUBUNIT_TUNER, + eST_CA = AVC1394_SUBUNIT_CA, + eST_Camera = AVC1394_SUBUNIT_VIDEO_CAMERA, + eST_Panel = AVC1394_SUBUNIT_PANEL, + eST_BulltinBoard = AVC1394_SUBUNIT_BULLETIN_BOARD, + eST_CameraStorage = AVC1394_SUBUNIT_CAMERA_STORAGE, + eST_Music = AVC1394_SUBUNIT_MUSIC, + eST_VendorUnique = AVC1394_SUBUNIT_VENDOR_UNIQUE, + eST_Reserved = AVC1394_SUBUNIT_RESERVED, + eST_Extended = AVC1394_SUBUNIT_EXTENDED, + eST_Unit = AVC1394_SUBUNIT_UNIT, +}; + +enum ESubunitType byteToSubunitType(byte_t s); + /** * \brief the possible sampling frequencies @@ -118,14 +153,19 @@ std::ostream& operator<<( std::ostream& stream, ESamplingFrequency samplingFrequency ); -#define AVC1394_SUBUNIT_AUDIO 1 -#define AVC1394_SUBUNIT_PRINTER 2 -#define AVC1394_SUBUNIT_CA 6 -#define AVC1394_SUBUNIT_PANEL 9 -#define AVC1394_SUBUNIT_BULLETIN_BOARD 0xA -#define AVC1394_SUBUNIT_CAMERA_STORAGE 0xB -#define AVC1394_SUBUNIT_MUSIC 0xC -#define AVC1394_SUBUNIT_RESERVED 0x1D +/** + * \brief Convert from a FDF SFC field value to an integer sample rate + * @param fdf fdf sfc field value + * @return sample rate + */ +unsigned int fdfSfcToSampleRate(byte_t fdf); -#define AVC1394_SUBUNIT_ID_RESERVED 0x06 +/** + * \brief Convert from an integer sample rate to a78 FDF SFC field value + * @param rate integer sample rate + * @return fdf sfc field value + */ +byte_t sampleRateToFdfSfc(unsigned int rate); -#endif // AVDDEFINITIONS_H +} + +#endif // AVCDEFINITIONS_H Index: trunk/libffado/src/libavc/musicsubunit/avc_musicsubunit.cpp =================================================================== --- trunk/libffado/src/libavc/musicsubunit/avc_musicsubunit.cpp (revision 548) +++ trunk/libffado/src/libavc/musicsubunit/avc_musicsubunit.cpp (revision 548) @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2007 by Pieter Palmers + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#warning this header should go +#include "bebob/bebob_avplug.h" +#include "libieee1394/configrom.h" + +#include "../general/avc_subunit.h" +#include "../general/avc_unit.h" + +#include "../general/avc_plug_info.h" +#include "../streamformat/avc_extended_stream_format.h" +#include "../util/avc_serialize.h" + +#include "avc_musicsubunit.h" +#include "avc_descriptor_music.h" + +#include + +namespace AVC { + +//////////////////////////////////////////// + +SubunitMusic::SubunitMusic( Unit& unit, subunit_t id ) + : Subunit( unit, eST_Music, id ) + , m_status_descriptor ( new AVCMusicStatusDescriptor( &unit, this ) ) +{ + +} + +SubunitMusic::SubunitMusic() + : Subunit() + , m_status_descriptor ( NULL ) +{ +} + +SubunitMusic::~SubunitMusic() +{ + if (m_status_descriptor) delete m_status_descriptor; +} + +bool +SubunitMusic::discover() +{ + debugOutput(DEBUG_LEVEL_NORMAL, "Discovering %s...\n", getName()); + + // discover the AV/C generic part + if ( !Subunit::discover() ) { + return false; + } + + // now we have the subunit plugs + + return true; +} + +bool +SubunitMusic::initPlugFromDescriptor( Plug& plug ) +{ + debugOutput(DEBUG_LEVEL_VERBOSE, "Loading info from descriptor for plug: \n"); + bool result=true; + + // load the descriptor (if not already loaded) + if (m_status_descriptor != NULL) { + result &= m_status_descriptor->load(); + } + + AVCMusicSubunitPlugInfoBlock *info; + info = m_status_descriptor->getSubunitPlugInfoBlock(plug.getDirection(), plug.getPlugId()); + + if (info == NULL) { + debugError("Could not find plug info block\n"); + return false; + } + + debugOutput(DEBUG_LEVEL_VERBOSE, "Found plug: %s\n",info->getName().c_str()); + + // plug name + result &= plug.setName(info->getName()); + + // plug type + switch (info->m_plug_type) { + case AVCMusicSubunitPlugInfoBlock::ePT_IsoStream: + result &= plug.setPlugType(Plug::eAPT_IsoStream); + break; + case AVCMusicSubunitPlugInfoBlock::ePT_AsyncStream: + result &= plug.setPlugType(Plug::eAPT_AsyncStream); + break; + case AVCMusicSubunitPlugInfoBlock::ePT_Midi: + result &= plug.setPlugType(Plug::eAPT_Midi); + break; + case AVCMusicSubunitPlugInfoBlock::ePT_Sync: + result &= plug.setPlugType(Plug::eAPT_Sync); + break; + case AVCMusicSubunitPlugInfoBlock::ePT_Analog: + result &= plug.setPlugType(Plug::eAPT_Analog); + break; + case AVCMusicSubunitPlugInfoBlock::ePT_Digital: + result &= plug.setPlugType(Plug::eAPT_Digital); + break; + } + + // number of channels + result &= plug.setNrOfChannels(info->m_nb_channels); + + int idx=1; + for ( AVCMusicClusterInfoBlockVectorIterator it = info->m_Clusters.begin(); + it != info->m_Clusters.end(); + ++it ) + { + struct Plug::ClusterInfo cinfo; + + AVCMusicClusterInfoBlock *c=(*it); + + cinfo.m_index=idx; //FIXME: is this correct? + cinfo.m_portType=c->m_port_type; + cinfo.m_nrOfChannels=c->m_nb_signals; + cinfo.m_streamFormat=c->m_stream_format; + cinfo.m_name=c->getName(); + + debugOutput(DEBUG_LEVEL_VERBOSE, "Adding cluster idx=%2d type=%02X nbch=%2d fmt=%02X name=%s\n", + cinfo.m_index, cinfo.m_portType, cinfo.m_nrOfChannels, cinfo.m_streamFormat, cinfo.m_name.c_str()); + + for ( AVCMusicClusterInfoBlock::SignalInfoVectorIterator sig_it + = c->m_SignalInfos.begin(); + sig_it != c->m_SignalInfos.end(); + ++sig_it ) + { + struct AVCMusicClusterInfoBlock::sSignalInfo s=(*sig_it); + struct Plug::ChannelInfo sinfo; + + sinfo.m_streamPosition=s.stream_position; + sinfo.m_location=s.stream_location; + + AVCMusicPlugInfoBlock *mplug=m_status_descriptor->getMusicPlugInfoBlock(s.music_plug_id); + + if (mplug==NULL) { + debugWarning("No music plug found for this signal\n"); + sinfo.m_name="unknown"; + } else { + sinfo.m_name=mplug->getName(); + } + + if (plug.getDirection() == Plug::eAPD_Input) { + // it's an input plug to the subunit + // so we have to check the source field of the music plug + if(s.stream_position != mplug->m_source_stream_position) { + debugWarning("s.stream_position (= 0x%02X) != mplug->m_source_stream_position (= 0x%02X)\n", + s.stream_position, mplug->m_source_stream_position); + // use the one from the music plug + sinfo.m_streamPosition= mplug->m_source_stream_position; + } + if(s.stream_location != mplug->m_source_stream_location) { + debugWarning("s.stream_location (= 0x%02X) != mplug->m_source_stream_location (= 0x%02X)\n", + s.stream_location, mplug->m_source_stream_location); + // use the one from the music plug + sinfo.m_location=mplug->m_source_stream_location; + } + } else if (plug.getDirection() == Plug::eAPD_Output) { + // it's an output plug from the subunit + // so we have to check the destination field of the music plug + if(s.stream_position != mplug->m_dest_stream_position) { + debugWarning("s.stream_position (= 0x%02X) != mplug->m_dest_stream_position (= 0x%02X)\n", + s.stream_position, mplug->m_dest_stream_position); + // use the one from the music plug + sinfo.m_streamPosition=mplug->m_dest_stream_position; + } + if(s.stream_location != mplug->m_dest_stream_location) { + debugWarning("s.stream_location (= 0x%02X) != mplug->m_dest_stream_location (= 0x%02X)\n", + s.stream_location, mplug->m_dest_stream_location); + // use the one from the music plug + sinfo.m_location=mplug->m_dest_stream_location; + } + } else { + debugWarning("Invalid plug direction.\n"); + } + + debugOutput(DEBUG_LEVEL_VERBOSE, "Adding signal pos=%2d loc=%2d name=%s\n", + sinfo.m_streamPosition, sinfo.m_location, mplug->getName().c_str()); + + cinfo.m_channelInfos.push_back(sinfo); + } + + idx++; + plug.getClusterInfos().push_back(cinfo); + } + + + return result; + +} + +bool +SubunitMusic::loadDescriptors() +{ + bool result=true; + if (m_status_descriptor != NULL) { + result &= m_status_descriptor->load(); + } else { + debugError("BUG: m_status_descriptor == NULL\n"); + return false; + } + return result; +} + +void SubunitMusic::setVerboseLevel(int l) +{ + Subunit::setVerboseLevel(l); + if (m_status_descriptor != NULL) { + m_status_descriptor->setVerboseLevel(l); + } +} + +const char* +SubunitMusic::getName() +{ + return "MusicSubunit"; +} + +bool +SubunitMusic::serializeChild( Glib::ustring basePath, + Util::IOSerialize& ser ) const +{ + return true; +} + +bool +SubunitMusic::deserializeChild( Glib::ustring basePath, + Util::IODeserialize& deser, + Unit& unit ) +{ + return true; +} + +} Index: trunk/libffado/src/libavc/musicsubunit/avc_descriptor_music.cpp =================================================================== --- trunk/libffado/src/libavc/musicsubunit/avc_descriptor_music.cpp (revision 524) +++ trunk/libffado/src/libavc/musicsubunit/avc_descriptor_music.cpp (revision 524) @@ -0,0 +1,732 @@ +/* + * Copyright (C) 2007 by Pieter Palmers + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_descriptor_music.h" + +#include "../descriptors/avc_descriptor.h" +#include "../descriptors/avc_descriptor_cmd.h" + +#include "../util/avc_serialize.h" +#include "libieee1394/ieee1394service.h" + +#include "../general/avc_subunit.h" +#include "../general/avc_unit.h" + +#include + +// info block implementations + +namespace AVC { + + +AVCMusicGeneralStatusInfoBlock::AVCMusicGeneralStatusInfoBlock( ) + : AVCInfoBlock( 0x8100 ) + , m_current_transmit_capability ( 0 ) + , m_current_receive_capability ( 0 ) + , m_current_latency_capability ( 0xFFFFFFFF ) +{} + +bool +AVCMusicGeneralStatusInfoBlock::serialize( IOSSerialize& se ) +{ + bool result=true; + result &= AVCInfoBlock::serialize(se); + + quadlet_t tmp=htonl(m_current_latency_capability); + + result &= se.write(m_current_transmit_capability, "AVCMusicGeneralStatusInfoBlock m_current_transmit_capability"); + result &= se.write(m_current_receive_capability, "AVCMusicGeneralStatusInfoBlock m_current_receive_capability"); + result &= se.write(tmp, "AVCMusicGeneralStatusInfoBlock m_current_latency_capability"); + + return result; +} + +bool +AVCMusicGeneralStatusInfoBlock::deserialize( IISDeserialize& de ) +{ + bool result=true; + result &= AVCInfoBlock::deserialize(de); + if (m_primary_field_length != 6) { + debugWarning("Incorrect primary field length: %u, should be 6\n", m_primary_field_length); + return false; + } + + result &= de.read(&m_current_transmit_capability); + result &= de.read(&m_current_receive_capability); + result &= de.read(&m_current_latency_capability); + m_current_latency_capability=ntohl(m_current_latency_capability); + + return result; +} + +// --------- +AVCMusicOutputPlugStatusInfoBlock::AVCMusicOutputPlugStatusInfoBlock( ) + : AVCInfoBlock( 0x8101 ) +{} + +bool +AVCMusicOutputPlugStatusInfoBlock::serialize( IOSSerialize& se ) +{ + bool result=true; + result &= AVCInfoBlock::serialize(se); + debugWarning("%s not supported\n", getInfoBlockName()); + result=false; + return result; +} + +bool +AVCMusicOutputPlugStatusInfoBlock::deserialize( IISDeserialize& de ) +{ + bool result=true; + result &= AVCInfoBlock::deserialize(de); + debugWarning("%s not supported, skipping\n", getInfoBlockName()); + de.skip(m_compound_length-4); + return result; +} +// --------- +AVCMusicClusterInfoBlock::AVCMusicClusterInfoBlock( ) + : AVCInfoBlock( 0x810A ) + , m_stream_format ( 0 ) + , m_port_type ( 0 ) + , m_nb_signals ( 0 ) +{} + +AVCMusicClusterInfoBlock::~AVCMusicClusterInfoBlock( ) +{ + clear(); +} + +bool +AVCMusicClusterInfoBlock::clear( ) { + m_stream_format=0; + m_port_type=0; + m_nb_signals=0; + + m_SignalInfos.clear(); + return true; +} + +bool +AVCMusicClusterInfoBlock::serialize( IOSSerialize& se ) +{ + bool result=true; + result &= AVCInfoBlock::serialize(se); + + result &= se.write(m_stream_format, "AVCMusicClusterInfoBlock m_stream_format"); + result &= se.write(m_port_type, "AVCMusicClusterInfoBlock m_port_type"); + result &= se.write(m_nb_signals, "AVCMusicClusterInfoBlock m_nb_signals"); + + if (m_SignalInfos.size() != m_nb_signals) { + debugError("not enough elements in AVCMusicClusterInfoBlock vector\n"); + return false; + } + + unsigned int cnt; + for (cnt=0;cnt0) { + result &= m_RawTextInfoBlock.serialize(se); + } else if (m_NameInfoBlock.m_compound_length>0) { + result &= m_NameInfoBlock.serialize(se); + } + + return result; +} + +bool +AVCMusicClusterInfoBlock::deserialize( IISDeserialize& de ) +{ + bool result=true; + result &= AVCInfoBlock::deserialize(de); + + unsigned int consumed_at_start=de.getNrOfConsumedBytes(); + + result &= de.read(&m_stream_format); + result &= de.read(&m_port_type); + result &= de.read(&m_nb_signals); + + unsigned int cnt; + for (cnt=0;cnt0) { + uint16_t block_type; + AVCInfoBlock::peekBlockType(de, &block_type); + if(block_type==m_RawTextInfoBlock.m_supported_info_block_type) { + result &= m_RawTextInfoBlock.deserialize(de); + } else if (block_type==m_NameInfoBlock.m_supported_info_block_type) { + result &= m_NameInfoBlock.deserialize(de); + } else { + debugWarning("Unexpected info block, skipping...\n"); + de.skip(bytes_left); + } + } + + return result; +} + +std::string +AVCMusicClusterInfoBlock::getName() { + if(m_RawTextInfoBlock.m_compound_length>0) { + return m_RawTextInfoBlock.m_text; + } else if (m_NameInfoBlock.m_compound_length>0) { + return m_NameInfoBlock.m_text; + } else { + return std::string("Unknown"); + } +} + + +// --------- +AVCMusicSubunitPlugInfoBlock::AVCMusicSubunitPlugInfoBlock( ) + : AVCInfoBlock( 0x8109 ) + , m_subunit_plug_id ( 0 ) + , m_signal_format ( 0 ) + , m_plug_type ( 0xFF ) + , m_nb_clusters ( 0 ) + , m_nb_channels ( 0 ) +{} + +AVCMusicSubunitPlugInfoBlock::~AVCMusicSubunitPlugInfoBlock( ) +{ + clear(); +} + +bool +AVCMusicSubunitPlugInfoBlock::clear() +{ + m_subunit_plug_id=0; + m_signal_format=0; + m_plug_type=0xFF; + m_nb_clusters=0; + m_nb_channels=0; + + // clean up dynamically allocated stuff + for ( AVCMusicClusterInfoBlockVectorIterator it = m_Clusters.begin(); + it != m_Clusters.end(); + ++it ) + { + delete *it; + } + m_Clusters.clear(); + + return true; +} + +bool +AVCMusicSubunitPlugInfoBlock::serialize( IOSSerialize& se ) +{ + bool result=true; + result &= AVCInfoBlock::serialize(se); + + result &= se.write(m_subunit_plug_id, "AVCMusicPlugInfoBlock m_subunit_plug_id"); + result &= se.write(m_signal_format, "AVCMusicPlugInfoBlock m_signal_format"); + result &= se.write(m_plug_type, "AVCMusicPlugInfoBlock m_plug_type"); + result &= se.write(m_nb_clusters, "AVCMusicPlugInfoBlock m_nb_clusters"); + result &= se.write(m_nb_channels, "AVCMusicPlugInfoBlock m_nb_channels"); + + unsigned int cnt; + if (m_Clusters.size() != m_nb_clusters) { + debugError("not enough elements in AVCMusicClusterInfoBlock vector\n"); + return false; + } + for (cnt=0;cntserialize(se); + } + + // do the optional text/name info block + if(m_RawTextInfoBlock.m_compound_length>0) { + result &= m_RawTextInfoBlock.serialize(se); + } else if (m_NameInfoBlock.m_compound_length>0) { + result &= m_NameInfoBlock.serialize(se); + } + return result; +} + +bool +AVCMusicSubunitPlugInfoBlock::deserialize( IISDeserialize& de ) +{ + bool result=true; + result &= AVCInfoBlock::deserialize(de); + + if (m_primary_field_length != 8) { + debugWarning("Incorrect primary field length: %u, should be 4\n", m_primary_field_length); + return false; + } + + unsigned int consumed_at_start=de.getNrOfConsumedBytes(); + + result &= de.read(&m_subunit_plug_id); + result &= de.read(&m_signal_format); + result &= de.read(&m_plug_type); + result &= de.read(&m_nb_clusters); + result &= de.read(&m_nb_channels); + + unsigned int cnt; + for (cnt=0;cntdeserialize(de); + } + unsigned int consumed_at_cluster_end=de.getNrOfConsumedBytes(); + + // do the optional text info block + // first find out if the block is present + int bytes_done=4+consumed_at_cluster_end-consumed_at_start; + int bytes_left=m_compound_length-bytes_done; + debugOutput(DEBUG_LEVEL_VERBOSE,"len=%d, @start=%d @end=%d done=%d, left=%d\n", + m_compound_length, consumed_at_start, consumed_at_cluster_end, bytes_done, bytes_left); + if(bytes_left>0) { + uint16_t block_type; + AVCInfoBlock::peekBlockType(de, &block_type); + if(block_type==m_RawTextInfoBlock.m_supported_info_block_type) { + result &= m_RawTextInfoBlock.deserialize(de); + } else if (block_type==m_NameInfoBlock.m_supported_info_block_type) { + result &= m_NameInfoBlock.deserialize(de); + } else { + debugWarning("Unexpected info block, skipping...\n"); + de.skip(bytes_left); + } + } + + return result; +} + +std::string +AVCMusicSubunitPlugInfoBlock::getName() { + if(m_RawTextInfoBlock.m_compound_length>0) { + return m_RawTextInfoBlock.m_text; + } else if (m_NameInfoBlock.m_compound_length>0) { + return m_NameInfoBlock.m_text; + } else { + return std::string("Unknown"); + } +} + + +// --------- +AVCMusicPlugInfoBlock::AVCMusicPlugInfoBlock( ) + : AVCInfoBlock( 0x810B ) + , m_music_plug_type ( 0 ) + , m_music_plug_id ( 0 ) + , m_routing_support ( 0 ) + , m_source_plug_function_type ( 0 ) + , m_source_plug_id ( 0 ) + , m_source_plug_function_block_id ( 0 ) + , m_source_stream_position ( 0 ) + , m_source_stream_location ( 0 ) + , m_dest_plug_function_type ( 0 ) + , m_dest_plug_id ( 0 ) + , m_dest_plug_function_block_id ( 0 ) + , m_dest_stream_position ( 0 ) + , m_dest_stream_location ( 0 ) +{} + +bool +AVCMusicPlugInfoBlock::clear( ) { + m_music_plug_type=0; + m_music_plug_id=0; + m_routing_support=0; + m_source_plug_function_type=0; + m_source_plug_id=0; + m_source_plug_function_block_id=0; + m_source_stream_position=0; + m_source_stream_location=0; + m_dest_plug_function_type=0; + m_dest_plug_id=0; + m_dest_plug_function_block_id=0; + m_dest_stream_position=0; + m_dest_stream_location=0; + + return true; +} + +bool +AVCMusicPlugInfoBlock::serialize( IOSSerialize& se ) +{ + bool result=true; + result &= AVCInfoBlock::serialize(se); + + result &= se.write(m_music_plug_type, "AVCMusicPlugInfoBlock m_music_plug_type" ); + result &= se.write(m_music_plug_id, "AVCMusicPlugInfoBlock m_music_plug_id" ); + result &= se.write(m_routing_support, "AVCMusicPlugInfoBlock m_routing_support" ); + result &= se.write(m_source_plug_function_type, "AVCMusicPlugInfoBlock m_source_plug_function_type" ); + result &= se.write(m_source_plug_id, "AVCMusicPlugInfoBlock m_source_plug_id" ); + result &= se.write(m_source_plug_function_block_id, "AVCMusicPlugInfoBlock m_source_plug_function_block_id" ); + result &= se.write(m_source_stream_position, "AVCMusicPlugInfoBlock m_source_stream_position" ); + result &= se.write(m_source_stream_location, "AVCMusicPlugInfoBlock m_source_stream_location" ); + result &= se.write(m_dest_plug_function_type, "AVCMusicPlugInfoBlock m_dest_plug_function_type" ); + result &= se.write(m_dest_plug_id, "AVCMusicPlugInfoBlock m_dest_plug_id" ); + result &= se.write(m_dest_plug_function_block_id, "AVCMusicPlugInfoBlock m_dest_plug_function_block_id" ); + result &= se.write(m_dest_stream_position, "AVCMusicPlugInfoBlock m_dest_stream_position" ); + result &= se.write(m_dest_stream_location, "AVCMusicPlugInfoBlock m_dest_stream_location" ); + + // do the optional text/name info block + if(m_RawTextInfoBlock.m_compound_length>0) { + result &= m_RawTextInfoBlock.serialize(se); + } else if (m_NameInfoBlock.m_compound_length>0) { + result &= m_NameInfoBlock.serialize(se); + } + + return result; +} + +bool +AVCMusicPlugInfoBlock::deserialize( IISDeserialize& de ) +{ + bool result=true; + result &= AVCInfoBlock::deserialize(de); + + if (m_primary_field_length != 14) { + debugWarning("Incorrect primary field length: %u, should be 4\n", m_primary_field_length); + return false; + } + + result &= de.read(&m_music_plug_type); + result &= de.read(&m_music_plug_id); + result &= de.read(&m_routing_support); + result &= de.read(&m_source_plug_function_type); + result &= de.read(&m_source_plug_id); + result &= de.read(&m_source_plug_function_block_id); + result &= de.read(&m_source_stream_position); + result &= de.read(&m_source_stream_location); + result &= de.read(&m_dest_plug_function_type); + result &= de.read(&m_dest_plug_id); + result &= de.read(&m_dest_plug_function_block_id); + result &= de.read(&m_dest_stream_position); + result &= de.read(&m_dest_stream_location); + + if(m_compound_length>18) { + uint16_t block_type; + AVCInfoBlock::peekBlockType(de, &block_type); + if(block_type==m_RawTextInfoBlock.m_supported_info_block_type) { + result &= m_RawTextInfoBlock.deserialize(de); + } else if (block_type==m_NameInfoBlock.m_supported_info_block_type) { + result &= m_NameInfoBlock.deserialize(de); + } else { + debugWarning("Unexpected info block, skipping...\n"); + de.skip(m_compound_length-18); + } + } + + return result; +} + +std::string +AVCMusicPlugInfoBlock::getName() { + if(m_RawTextInfoBlock.m_compound_length>0) { + return m_RawTextInfoBlock.m_text; + } else if (m_NameInfoBlock.m_compound_length>0) { + return m_NameInfoBlock.m_text; + } else { + return std::string("Unknown"); + } +} + + +// --------- +AVCMusicRoutingStatusInfoBlock::AVCMusicRoutingStatusInfoBlock( ) + : AVCInfoBlock( 0x8108 ) + , m_nb_dest_plugs ( 0 ) + , m_nb_source_plugs ( 0 ) + , m_nb_music_plugs ( 0 ) +{} + +AVCMusicRoutingStatusInfoBlock::~AVCMusicRoutingStatusInfoBlock( ) { + + clear(); +} + +bool +AVCMusicRoutingStatusInfoBlock::clear() +{ + m_nb_dest_plugs=0; + m_nb_source_plugs=0; + m_nb_music_plugs=0; + + // clean up dynamically allocated stuff + for ( AVCMusicSubunitPlugInfoBlockVectorIterator it = mDestPlugInfoBlocks.begin(); + it != mDestPlugInfoBlocks.end(); + ++it ) + { + delete *it; + } + mDestPlugInfoBlocks.clear(); + + for ( AVCMusicSubunitPlugInfoBlockVectorIterator it = mSourcePlugInfoBlocks.begin(); + it != mSourcePlugInfoBlocks.end(); + ++it ) + { + delete *it; + } + mSourcePlugInfoBlocks.clear(); + + for ( AVCMusicPlugInfoBlockVectorIterator it = mMusicPlugInfoBlocks.begin(); + it != mMusicPlugInfoBlocks.end(); + ++it ) + { + delete *it; + } + mMusicPlugInfoBlocks.clear(); + + return true; +} + +bool +AVCMusicRoutingStatusInfoBlock::serialize( IOSSerialize& se ) +{ + bool result=true; + result &= AVCInfoBlock::serialize(se); + + result &= se.write(m_nb_dest_plugs, "AVCMusicRoutingStatusInfoBlock m_nb_dest_plugs"); + result &= se.write(m_nb_source_plugs, "AVCMusicRoutingStatusInfoBlock m_nb_source_plugs"); + result &= se.write(m_nb_music_plugs, "AVCMusicRoutingStatusInfoBlock m_nb_music_plugs"); + + unsigned int cnt; + if (mDestPlugInfoBlocks.size() != m_nb_dest_plugs) { + debugError("not enough elements in dest AVCMusicSubunitPlugInfoBlock vector\n"); + return false; + } + for (cnt=0;cntserialize(se); + } + + if (mSourcePlugInfoBlocks.size() != m_nb_source_plugs) { + debugError("not enough elements in src AVCMusicSubunitPlugInfoBlock\n"); + return false; + } + for (cnt=0;cntserialize(se); + } + + if (mMusicPlugInfoBlocks.size() != m_nb_music_plugs) { + debugError("not enough elements in AVCMusicPlugInfoBlock\n"); + return false; + } + for (cnt=0;cntserialize(se); + } + + return result; +} + +bool +AVCMusicRoutingStatusInfoBlock::deserialize( IISDeserialize& de ) +{ + bool result=true; + result &= AVCInfoBlock::deserialize(de); + + if (m_primary_field_length != 4) { + debugWarning("Incorrect primary field length: %u, should be 4\n", m_primary_field_length); + return false; + } + + result &= de.read(&m_nb_dest_plugs); + result &= de.read(&m_nb_source_plugs); + result &= de.read(&m_nb_music_plugs); + + unsigned int cnt; + for (cnt=0;cntdeserialize(de); + } + + for (cnt=0;cntdeserialize(de); + } + + for (cnt=0;cntdeserialize(de); + } + return result; +} + +AVCMusicSubunitPlugInfoBlock * +AVCMusicRoutingStatusInfoBlock::getSubunitPlugInfoBlock(Plug::EPlugDirection direction, plug_id_t id) { + if (direction == Plug::eAPD_Input) { + for ( AVCMusicSubunitPlugInfoBlockVectorIterator it = mDestPlugInfoBlocks.begin(); + it != mDestPlugInfoBlocks.end(); + ++it ) + { + AVCMusicSubunitPlugInfoBlock *b=(*it); + if (b->m_subunit_plug_id == id) return b; + } + debugOutput(DEBUG_LEVEL_VERBOSE, "no plug info found.\n"); + return NULL; + } else if (direction == Plug::eAPD_Output) { + for ( AVCMusicSubunitPlugInfoBlockVectorIterator it = mSourcePlugInfoBlocks.begin(); + it != mSourcePlugInfoBlocks.end(); + ++it ) + { + AVCMusicSubunitPlugInfoBlock *b=(*it); + if (b->m_subunit_plug_id == id) return b; + } + debugOutput(DEBUG_LEVEL_VERBOSE, "no plug info found.\n"); + return NULL; + } else { + debugOutput(DEBUG_LEVEL_VERBOSE, "Invalid direction.\n"); + return NULL; + } +} + +AVCMusicPlugInfoBlock * +AVCMusicRoutingStatusInfoBlock::getMusicPlugInfoBlock(plug_id_t id) { + for ( AVCMusicPlugInfoBlockVectorIterator it = mMusicPlugInfoBlocks.begin(); + it != mMusicPlugInfoBlocks.end(); + ++it ) + { + AVCMusicPlugInfoBlock *b=(*it); + if (b->m_music_plug_id == id) return b; + } + debugOutput(DEBUG_LEVEL_VERBOSE, "no music plug info found.\n"); + return NULL; +} + +// ---------------------- +AVCMusicStatusDescriptor::AVCMusicStatusDescriptor( Unit* unit, Subunit* subunit ) + : AVCDescriptor(unit, subunit, AVCDescriptorSpecifier::eSubunit0x80) +{} + +bool +AVCMusicStatusDescriptor::serialize( IOSSerialize& se ) +{ + bool result=true; + + result &= AVCDescriptor::serialize(se); + + result &= m_general_status_infoblock.serialize(se); + + if (m_output_plug_status_infoblock.m_compound_length>0) { + result &= m_output_plug_status_infoblock.serialize(se); + } + + if (m_routing_status_infoblock.m_compound_length>0) { + result &= m_routing_status_infoblock.serialize(se); + } + + return true; +} + +bool +AVCMusicStatusDescriptor::deserialize( IISDeserialize& de ) +{ + bool result=true; + + unsigned int blocks_done=0; + const unsigned int max_blocks=10; + + result &= AVCDescriptor::deserialize(de); + + uint16_t block_type; + uint16_t block_length; + + // process all infoblocks until done or until failure + while(AVCInfoBlock::peekBlockType(de, &block_type) && result) { + AVCInfoBlock::peekBlockLength(de, &block_length); + + debugOutput(DEBUG_LEVEL_VERBOSE, "type=0x%04X, length=%u\n",block_type, block_length); + + switch (block_type) { + case 0x8100: + m_general_status_infoblock.setVerbose(getVerboseLevel()); + result &= m_general_status_infoblock.deserialize(de); + break; + case 0x8101: + m_output_plug_status_infoblock.setVerbose(getVerboseLevel()); + result &= m_output_plug_status_infoblock.deserialize(de); + break; + case 0x8108: + m_routing_status_infoblock.setVerbose(getVerboseLevel()); + result &= m_routing_status_infoblock.deserialize(de); + break; + default: + debugWarning("Unknown info block type: 0x%04X, length=%u, skipping...\n", block_type, block_length); + de.skip(block_length); + break; + } + + if(blocks_done++>max_blocks) { + debugError("Too much info blocks in descriptor, probably a runaway parser\n"); + break; + } + } + + return result; +} + +AVCMusicSubunitPlugInfoBlock * +AVCMusicStatusDescriptor::getSubunitPlugInfoBlock(Plug::EPlugDirection direction, plug_id_t id) { + return m_routing_status_infoblock.getSubunitPlugInfoBlock(direction, id); +} + +AVCMusicPlugInfoBlock * +AVCMusicStatusDescriptor::getMusicPlugInfoBlock(plug_id_t id) { + return m_routing_status_infoblock.getMusicPlugInfoBlock(id); +} + +} Index: trunk/libffado/src/libavc/musicsubunit/avc_musicsubunit.h =================================================================== --- trunk/libffado/src/libavc/musicsubunit/avc_musicsubunit.h (revision 524) +++ trunk/libffado/src/libavc/musicsubunit/avc_musicsubunit.h (revision 524) @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007 by Pieter Palmers + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVC_MUSICSUBUNIT_H +#define AVC_MUSICSUBUNIT_H + +#include +#include "libutil/serialize.h" + +namespace AVC { + +class Unit; +class Plug; +class AVCMusicStatusDescriptor; + +// ///////////////////////////// + +class SubunitMusic: public Subunit { + public: + SubunitMusic( Unit& avDevice, + subunit_t id ); + SubunitMusic(); + virtual ~SubunitMusic(); + + virtual bool discover(); + virtual bool initPlugFromDescriptor( Plug& plug ); + + virtual bool loadDescriptors(); + + virtual void setVerboseLevel(int l); + virtual const char* getName(); +protected: + virtual bool serializeChild( Glib::ustring basePath, + Util::IOSerialize& ser ) const; + virtual bool deserializeChild( Glib::ustring basePath, + Util::IODeserialize& deser, + Unit& avDevice ); + + class AVCMusicStatusDescriptor* m_status_descriptor; +}; + +} + +#endif Index: trunk/libffado/src/libavc/musicsubunit/avc_descriptor_music.h =================================================================== --- trunk/libffado/src/libavc/musicsubunit/avc_descriptor_music.h (revision 524) +++ trunk/libffado/src/libavc/musicsubunit/avc_descriptor_music.h (revision 524) @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2007 by Pieter Palmers + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +/** + * Implements the AV/C Descriptors/InfoBlocks for the Music Subunit as in TA2004007 + * + */ + +#ifndef AVCDESCRIPTORMUSIC_H +#define AVCDESCRIPTORMUSIC_H + +#include "../descriptors/avc_descriptor.h" +#include "../avc_definitions.h" + +#include "../general/avc_generic.h" +#include "../general/avc_plug.h" + +#include "debugmodule/debugmodule.h" + +#include + +#include +#include + +class Ieee1394Service; + +namespace AVC { + + +class IOSSerialize; +class IISDeserialize; + +/** + * The info blocks + */ +class AVCMusicGeneralStatusInfoBlock : public AVCInfoBlock +{ +public: + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + AVCMusicGeneralStatusInfoBlock( ); + virtual ~AVCMusicGeneralStatusInfoBlock() {}; + virtual const char* getInfoBlockName() const + {return "AVCMusicGeneralStatusInfoBlock";}; + + byte_t m_current_transmit_capability; + byte_t m_current_receive_capability; + quadlet_t m_current_latency_capability; + +protected: + +private: + +}; + +class AVCMusicOutputPlugStatusInfoBlock : public AVCInfoBlock +{ +public: + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + AVCMusicOutputPlugStatusInfoBlock( ); + virtual ~AVCMusicOutputPlugStatusInfoBlock() {}; + virtual const char* getInfoBlockName() const + {return "AVCMusicOutputPlugStatusInfoBlock";}; + +protected: + +private: + +}; + +class AVCMusicClusterInfoBlock : public AVCInfoBlock +{ +public: + + struct sSignalInfo { + uint16_t music_plug_id; + byte_t stream_position; + byte_t stream_location; + }; + typedef std::vector SignalInfoVector; + typedef std::vector::iterator SignalInfoVectorIterator; + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual bool clear(); + + std::string getName(); + + AVCMusicClusterInfoBlock( ); + virtual ~AVCMusicClusterInfoBlock(); + virtual const char* getInfoBlockName() const + {return "AVCMusicClusterInfoBlock";}; + + byte_t m_stream_format; + byte_t m_port_type; + byte_t m_nb_signals; + SignalInfoVector m_SignalInfos; + + AVCRawTextInfoBlock m_RawTextInfoBlock; + AVCNameInfoBlock m_NameInfoBlock; +protected: + +private: + +}; +typedef std::vector AVCMusicClusterInfoBlockVector; +typedef std::vector::iterator AVCMusicClusterInfoBlockVectorIterator; + +class AVCMusicSubunitPlugInfoBlock : public AVCInfoBlock +{ +public: + enum AVCMusicSubunitPlugInfoBlockPlugType { + ePT_IsoStream = 0x0, + ePT_AsyncStream = 0x1, + ePT_Midi = 0x2, + ePT_Sync = 0x3, + ePT_Analog = 0x4, + ePT_Digital = 0x5, + + ePT_Unknown = 0xff, + }; + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + AVCMusicSubunitPlugInfoBlock( ); + virtual ~AVCMusicSubunitPlugInfoBlock(); + virtual const char* getInfoBlockName() const + {return "AVCMusicSubunitPlugInfoBlock";}; + + virtual bool clear(); + + std::string getName(); + + byte_t m_subunit_plug_id; + uint16_t m_signal_format; + byte_t m_plug_type; + uint16_t m_nb_clusters; + uint16_t m_nb_channels; + + AVCMusicClusterInfoBlockVector m_Clusters; + AVCRawTextInfoBlock m_RawTextInfoBlock; + AVCNameInfoBlock m_NameInfoBlock; + +protected: + +private: + +}; +typedef std::vector AVCMusicSubunitPlugInfoBlockVector; +typedef std::vector::iterator AVCMusicSubunitPlugInfoBlockVectorIterator; + +class AVCMusicPlugInfoBlock : public AVCInfoBlock +{ +public: + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual bool clear(); + + AVCMusicPlugInfoBlock( ); + virtual ~AVCMusicPlugInfoBlock() {}; + virtual const char* getInfoBlockName() const + {return "AVCMusicPlugInfoBlock";}; + + std::string getName(); + + byte_t m_music_plug_type; + uint16_t m_music_plug_id; + byte_t m_routing_support; + byte_t m_source_plug_function_type; + byte_t m_source_plug_id; + byte_t m_source_plug_function_block_id; + byte_t m_source_stream_position; + byte_t m_source_stream_location; + byte_t m_dest_plug_function_type; + byte_t m_dest_plug_id; + byte_t m_dest_plug_function_block_id; + byte_t m_dest_stream_position; + byte_t m_dest_stream_location; + + AVCRawTextInfoBlock m_RawTextInfoBlock; + AVCNameInfoBlock m_NameInfoBlock; + +protected: + +private: + +}; +typedef std::vector AVCMusicPlugInfoBlockVector; +typedef std::vector::iterator AVCMusicPlugInfoBlockVectorIterator; + +class AVCMusicRoutingStatusInfoBlock : public AVCInfoBlock +{ +public: + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + AVCMusicRoutingStatusInfoBlock( ); + virtual ~AVCMusicRoutingStatusInfoBlock(); + virtual const char* getInfoBlockName() const + {return "AVCMusicRoutingStatusInfoBlock";}; + + AVCMusicSubunitPlugInfoBlock *getSubunitPlugInfoBlock(Plug::EPlugDirection, plug_id_t); + AVCMusicPlugInfoBlock *getMusicPlugInfoBlock(plug_id_t); + + virtual bool clear(); + + byte_t m_nb_dest_plugs; + byte_t m_nb_source_plugs; + uint16_t m_nb_music_plugs; + + AVCMusicSubunitPlugInfoBlockVector mDestPlugInfoBlocks; + AVCMusicSubunitPlugInfoBlockVector mSourcePlugInfoBlocks; + AVCMusicPlugInfoBlockVector mMusicPlugInfoBlocks; + +protected: + +private: + +}; + +/** + * + */ +class AVCMusicStatusDescriptor : public AVCDescriptor +{ + +public: + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + AVCMusicStatusDescriptor( Unit* unit, Subunit* subunit ); + virtual ~AVCMusicStatusDescriptor() {} + + virtual const char* getDescriptorName() const + {return "AVCMusicStatusDescriptor";}; + + AVCMusicSubunitPlugInfoBlock *getSubunitPlugInfoBlock(Plug::EPlugDirection, plug_id_t); + AVCMusicPlugInfoBlock *getMusicPlugInfoBlock(plug_id_t); + +private: + // the child info blocks + AVCMusicGeneralStatusInfoBlock m_general_status_infoblock; + AVCMusicOutputPlugStatusInfoBlock m_output_plug_status_infoblock; + AVCMusicRoutingStatusInfoBlock m_routing_status_infoblock; + +}; + +} + +#endif // AVCDESCRIPTORMUSIC_H Index: trunk/libffado/src/libavc/audiosubunit/avc_audiosubunit.cpp =================================================================== --- trunk/libffado/src/libavc/audiosubunit/avc_audiosubunit.cpp (revision 509) +++ trunk/libffado/src/libavc/audiosubunit/avc_audiosubunit.cpp (revision 509) @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2007 by Pieter Palmers + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_audiosubunit.h" +#include "../general/avc_subunit.h" + +#warning merge with bebob functionblock +#include "bebob/bebob_functionblock.h" +#include "../audiosubunit/avc_function_block.h" + + +#include + +namespace AVC { + +//////////////////////////////////////////// + +SubunitAudio::SubunitAudio( Unit& unit, subunit_t id ) + : Subunit( unit, eST_Audio, id ) +{ +} + +SubunitAudio::SubunitAudio() + : Subunit() +{ +} + +SubunitAudio::~SubunitAudio() +{ + for ( BeBoB::FunctionBlockVector::iterator it = m_functions.begin(); + it != m_functions.end(); + ++it ) + { + delete *it; + } +} + +bool +SubunitAudio::discover() +{ + debugOutput(DEBUG_LEVEL_NORMAL, "Discovering %s...\n", getName()); + + if ( !Subunit::discover() ) { + return false; + } + + return true; +} + + +const char* +SubunitAudio::getName() +{ + return "AVC::AudioSubunit"; +} + +// bool +// SubunitAudio::discoverConnections() +// { +// debugOutput(DEBUG_LEVEL_NORMAL, "Discovering connections...\n"); +// if ( !Subunit::discoverConnections() ) { +// return false; +// } +// +// for ( BeBoB::FunctionBlockVector::iterator it = m_functions.begin(); +// it != m_functions.end(); +// ++it ) +// { +// BeBoB::FunctionBlock* function = *it; +// if ( !function->discoverConnections() ) { +// debugError( "functionblock connection discovering failed ('%s')\n", +// function->getName() ); +// return false; +// } +// } +// +// return true; +// } +// bool +// SubunitAudio::discoverBeBoB::FunctionBlocks() +// { +// debugOutput( DEBUG_LEVEL_NORMAL, +// "Discovering function blocks...\n"); +// +// if ( !discoverBeBoB::FunctionBlocksDo( +// ExtendedSubunitInfoCmd::eFBT_AudioSubunitSelector) ) +// { +// debugError( "Could not discover function block selector\n" ); +// return false; +// } +// if ( !discoverBeBoB::FunctionBlocksDo( +// ExtendedSubunitInfoCmd::eFBT_AudioSubunitFeature) ) +// { +// debugError( "Could not discover function block feature\n" ); +// return false; +// } +// if ( !discoverBeBoB::FunctionBlocksDo( +// ExtendedSubunitInfoCmd::eFBT_AudioSubunitProcessing) ) +// { +// debugError( "Could not discover function block processing\n" ); +// return false; +// } +// if ( !discoverBeBoB::FunctionBlocksDo( +// ExtendedSubunitInfoCmd::eFBT_AudioSubunitCodec) ) +// { +// debugError( "Could not discover function block codec\n" ); +// return false; +// } +// +// // print a function block list +// #ifdef DEBUG +// if (getDebugLevel() >= DEBUG_LEVEL_NORMAL) { +// +// for ( BeBoB::FunctionBlockVector::iterator it = m_functions.begin(); +// it != m_functions.end(); +// ++it ) +// { +// debugOutput(DEBUG_LEVEL_NORMAL, "%20s FB, type 0x%X, id=%d\n", +// (*it)->getName(), +// (*it)->getType(), +// (*it)->getId()); +// } +// } +// #endif +// +// return true; +// } +// +// bool +// SubunitAudio::discoverBeBoB::FunctionBlocksDo( +// ExtendedSubunitInfoCmd::EBeBoB::FunctionBlockType fbType ) +// { +// int page = 0; +// bool cmdSuccess = false; +// bool finished = false; +// +// do { +// ExtendedSubunitInfoCmd +// extSubunitInfoCmd( m_unit->get1394Service() ); +// extSubunitInfoCmd.setNodeId( m_unit->getConfigRom().getNodeId() ); +// extSubunitInfoCmd.setCommandType( AVCCommand::eCT_Status ); +// extSubunitInfoCmd.setSubunitId( getSubunitId() ); +// extSubunitInfoCmd.setSubunitType( getSubunitType() ); +// extSubunitInfoCmd.setVerbose( m_verboseLevel ); +// +// extSubunitInfoCmd.m_fbType = fbType; +// extSubunitInfoCmd.m_page = page; +// +// cmdSuccess = extSubunitInfoCmd.fire(); +// if ( cmdSuccess +// && ( extSubunitInfoCmd.getResponse() +// == AVCCommand::eR_Implemented ) ) +// { +// for ( ExtendedSubunitInfoPageDataVector::iterator it = +// extSubunitInfoCmd.m_infoPageDatas.begin(); +// cmdSuccess +// && ( it != extSubunitInfoCmd.m_infoPageDatas.end() ); +// ++it ) +// { +// cmdSuccess = createBeBoB::FunctionBlock( fbType, **it ); +// } +// if ( ( extSubunitInfoCmd.m_infoPageDatas.size() != 0 ) +// && ( extSubunitInfoCmd.m_infoPageDatas.size() == 5 ) ) +// { +// page++; +// } else { +// finished = true; +// } +// } else { +// finished = true; +// } +// } while ( cmdSuccess && !finished ); +// +// return cmdSuccess; +// } +// +// bool +// SubunitAudio::createBeBoB::FunctionBlock( +// ExtendedSubunitInfoCmd::EBeBoB::FunctionBlockType fbType, +// ExtendedSubunitInfoPageData& data ) +// { +// BeBoB::FunctionBlock::ESpecialPurpose purpose +// = convertSpecialPurpose( data.m_functionBlockSpecialPupose ); +// +// BeBoB::FunctionBlock* fb = 0; +// +// switch ( fbType ) { +// case ExtendedSubunitInfoCmd::eFBT_AudioSubunitSelector: +// { +// fb = new BeBoB::FunctionBlockSelector( *this, +// data.m_functionBlockId, +// purpose, +// data.m_noOfInputPlugs, +// data.m_noOfOutputPlugs, +// m_verboseLevel ); +// } +// break; +// case ExtendedSubunitInfoCmd::eFBT_AudioSubunitFeature: +// { +// fb = new BeBoB::FunctionBlockFeature( *this, +// data.m_functionBlockId, +// purpose, +// data.m_noOfInputPlugs, +// data.m_noOfOutputPlugs, +// m_verboseLevel ); +// } +// break; +// case ExtendedSubunitInfoCmd::eFBT_AudioSubunitProcessing: +// { +// switch ( data.m_functionBlockType ) { +// case ExtendedSubunitInfoCmd::ePT_EnhancedMixer: +// { +// fb = new BeBoB::FunctionBlockEnhancedMixer( *this, +// data.m_functionBlockId, +// purpose, +// data.m_noOfInputPlugs, +// data.m_noOfOutputPlugs, +// m_verboseLevel ); +// } +// break; +// case ExtendedSubunitInfoCmd::ePT_Mixer: +// case ExtendedSubunitInfoCmd::ePT_Generic: +// case ExtendedSubunitInfoCmd::ePT_UpDown: +// case ExtendedSubunitInfoCmd::ePT_DolbyProLogic: +// case ExtendedSubunitInfoCmd::ePT_3DStereoExtender: +// case ExtendedSubunitInfoCmd::ePT_Reverberation: +// case ExtendedSubunitInfoCmd::ePT_Chorus: +// case ExtendedSubunitInfoCmd::ePT_DynamicRangeCompression: +// default: +// fb = new BeBoB::FunctionBlockProcessing( *this, +// data.m_functionBlockId, +// purpose, +// data.m_noOfInputPlugs, +// data.m_noOfOutputPlugs, +// m_verboseLevel ); +// debugWarning( "Dummy function block processing created. " +// "Implementation is missing\n" ); +// } +// } +// break; +// case ExtendedSubunitInfoCmd::eFBT_AudioSubunitCodec: +// { +// fb = new BeBoB::FunctionBlockCodec( *this, +// data.m_functionBlockId, +// purpose, +// data.m_noOfInputPlugs, +// data.m_noOfOutputPlugs, +// m_verboseLevel ); +// debugWarning( "Dummy function block codec created. " +// "Implementation is missing\n" ); +// } +// break; +// default: +// debugError( "Unhandled function block type found\n" ); +// return false; +// } +// +// if ( !fb ) { +// debugError( "Could create function block\n" ); +// return false; +// } +// if ( !fb->discover() ) { +// debugError( "Could not discover function block %s\n", +// fb->getName() ); +// delete fb; +// return false; +// } +// m_functions.push_back( fb ); +// +// return true; +// } +// +// BeBoB::FunctionBlock::ESpecialPurpose +// SubunitAudio::convertSpecialPurpose( +// function_block_special_purpose_t specialPurpose ) +// { +// BeBoB::FunctionBlock::ESpecialPurpose p; +// switch ( specialPurpose ) { +// case ExtendedSubunitInfoPageData::eSP_InputGain: +// p = BeBoB::FunctionBlock::eSP_InputGain; +// break; +// case ExtendedSubunitInfoPageData::eSP_OutputVolume: +// p = BeBoB::FunctionBlock::eSP_OutputVolume; +// break; +// default: +// p = BeBoB::FunctionBlock::eSP_NoSpecialPurpose; +// } +// return p; +// } +// +bool +SubunitAudio::serializeChild( Glib::ustring basePath, + Util::IOSerialize& ser ) const +{ + bool result = true; + int i = 0; + + for ( BeBoB::FunctionBlockVector::const_iterator it = m_functions.begin(); + it != m_functions.end(); + ++it ) + { + BeBoB::FunctionBlock* pFB = *it; + std::ostringstream strstrm; + strstrm << basePath << "BeBoB::FunctionBlock" << i << "/"; + + result &= pFB->serialize( strstrm.str() , ser ); + + i++; + } + + return result; +} + +bool +SubunitAudio::deserializeChild( Glib::ustring basePath, + Util::IODeserialize& deser, + Unit& unit ) +{ + int i = 0; + bool bFinished = false; + do { + std::ostringstream strstrm; + strstrm << basePath << "BeBoB::FunctionBlock" << i << "/"; + BeBoB::FunctionBlock* pFB = BeBoB::FunctionBlock::deserialize( strstrm.str(), + deser, + unit, + *this ); + if ( pFB ) { + m_functions.push_back( pFB ); + i++; + } else { + bFinished = true; + } + } while ( !bFinished ); + + return true; +} + +} Index: trunk/libffado/src/libavc/audiosubunit/avc_function_block.cpp =================================================================== --- trunk/libffado/src/libavc/audiosubunit/avc_function_block.cpp (revision 503) +++ trunk/libffado/src/libavc/audiosubunit/avc_function_block.cpp (revision 503) @@ -0,0 +1,709 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * Copyright (C) 2005-2007 by Pieter Palmers + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_function_block.h" +#include "../util/avc_serialize.h" +#include "libieee1394/ieee1394service.h" + + +namespace AVC { + + +///////////////////////////////// + +FunctionBlockFeatureVolume::FunctionBlockFeatureVolume() + : IBusData() + , m_controlDataLength( 2 ) + , m_volume( 0 ) +{ +} + +FunctionBlockFeatureVolume::FunctionBlockFeatureVolume( const FunctionBlockFeatureVolume& rhs ) + : m_controlDataLength( rhs.m_controlDataLength ) + , m_volume( rhs.m_volume ) +{ +} + +FunctionBlockFeatureVolume::~FunctionBlockFeatureVolume() +{ +} + +bool +FunctionBlockFeatureVolume::serialize( IOSSerialize& se ) +{ + bool bStatus; + byte_t val; + bStatus = se.write( m_controlDataLength, "FunctionBlockFeatureVolume controlDataLength" ); + val = (byte_t)(m_volume >> 8); + bStatus &= se.write( val, "FunctionBlockFeatureVolume volume high" ); + val = m_volume & 0xff; + bStatus &= se.write( val, "FunctionBlockFeatureVolume volume low" ); + + return bStatus; +} + +bool +FunctionBlockFeatureVolume::deserialize( IISDeserialize& de ) +{ + bool bStatus; + byte_t val; + bStatus = de.read( &m_controlDataLength ); + bStatus &= de.read( &val ); + m_volume = val << 8; + bStatus &= de.read( &val ); + m_volume |= val; + + return bStatus; +} + +FunctionBlockFeatureVolume* +FunctionBlockFeatureVolume::clone() const +{ + return new FunctionBlockFeatureVolume( *this ); +} + +///////////////////////////////// + +FunctionBlockProcessingMixer::FunctionBlockProcessingMixer() + : IBusData() + , m_controlSelector( FunctionBlockProcessing::eCSE_Processing_Mixer ) +{ +} + +FunctionBlockProcessingMixer::FunctionBlockProcessingMixer( const FunctionBlockProcessingMixer& rhs ) + : m_controlSelector( rhs.m_controlSelector ) +{ +} + +FunctionBlockProcessingMixer::~FunctionBlockProcessingMixer() +{ +} + +bool +FunctionBlockProcessingMixer::serialize( IOSSerialize& se ) +{ + bool bStatus; + bStatus = se.write( m_controlSelector, "FunctionBlockProcessingMixer controlSelector" ); + + return bStatus; +} + +bool +FunctionBlockProcessingMixer::deserialize( IISDeserialize& de ) +{ + bool bStatus; + bStatus = de.read( &m_controlSelector ); + + return bStatus; +} + +FunctionBlockProcessingMixer* +FunctionBlockProcessingMixer::clone() const +{ + return new FunctionBlockProcessingMixer( *this ); +} + +///////////////////////////////// + +FunctionBlockProcessingEnhancedMixer::FunctionBlockProcessingEnhancedMixer() + : IBusData() + , m_controlSelector( FunctionBlockProcessing::eCSE_Processing_EnhancedMixer ) + , m_statusSelector( eSS_ProgramableState ) +{ +} + +FunctionBlockProcessingEnhancedMixer::FunctionBlockProcessingEnhancedMixer( + const FunctionBlockProcessingEnhancedMixer& rhs ) + : m_controlSelector( rhs.m_controlSelector ) + , m_statusSelector( rhs.m_statusSelector ) +{ +} + +FunctionBlockProcessingEnhancedMixer::~FunctionBlockProcessingEnhancedMixer() +{ +} + +bool +FunctionBlockProcessingEnhancedMixer::serialize( IOSSerialize& se ) +{ + int todo,done; + bool bStatus; + byte_t data_length_hi, data_length_lo; + + bStatus = se.write( m_controlSelector, "FunctionBlockProcessingEnhancedMixer controlSelector" ); + bStatus &= se.write( m_statusSelector, "FunctionBlockProcessingEnhancedMixer statusSelector" ); + + switch (m_statusSelector) { + case eSS_ProgramableState: + m_controlDataLength=m_LevelData.size(); + data_length_hi=(m_controlDataLength >> 8); + data_length_lo=(m_controlDataLength & 0xFF); + bStatus &= se.write( data_length_hi, "FunctionBlockProcessingEnhancedMixer controlDataLengthHi" ); + bStatus &= se.write( data_length_lo, "FunctionBlockProcessingEnhancedMixer controlDataLengthLo" ); + + for (int i=0;i> 8); + data_length_lo=(m_controlDataLength & 0xFF); + bStatus &= se.write( data_length_hi, "FunctionBlockProcessingEnhancedMixer controlDataLengthHi" ); + bStatus &= se.write( data_length_lo, "FunctionBlockProcessingEnhancedMixer controlDataLengthLo" ); + + for (int i=0;i> 8; + byte_t value_lo=value & 0xFF; + + bStatus &= se.write( value_hi, "FunctionBlockProcessingEnhancedMixer data" ); + bStatus &= se.write( value_lo, "FunctionBlockProcessingEnhancedMixer data" ); + } + break; + } + return bStatus; +} + +bool +FunctionBlockProcessingEnhancedMixer::deserialize( IISDeserialize& de ) +{ + int todo; + bool bStatus=true; + bStatus = de.read( &m_controlSelector ); + + // NOTE: the returned value is currently bogus, so overwrite it + m_controlSelector=FunctionBlockProcessing::eCSE_Processing_EnhancedMixer; + + bStatus &= de.read( &m_statusSelector ); + + byte_t data_length_hi; + byte_t data_length_lo; + bStatus &= de.read( &data_length_hi ); + bStatus &= de.read( &data_length_lo ); + + m_controlDataLength = (data_length_hi << 8) + data_length_lo; + switch (m_statusSelector) { + case eSS_ProgramableState: + m_ProgramableStateData.clear(); + for (int i=0;i=0;j--) { + byte_t bit_value; + bit_value=(((1<7-todo;j--) { + byte_t bit_value; + bit_value=(((1<serialize( se ); + } else { + bStatus = false; + } + + return bStatus; +} + +bool +FunctionBlockFeature::deserialize( IISDeserialize& de ) +{ + bool bStatus; + bStatus = de.read( &m_selectorLength ); + bStatus &= de.read( &m_audioChannelNumber ); + bStatus &= de.read( &m_controlSelector ); + + switch( m_controlSelector ) { + case eCSE_Feature_Volume: + bStatus &= m_pVolume->deserialize( de ); + break; + case eCSE_Feature_Mute: + case eCSE_Feature_LRBalance: + case eCSE_Feature_FRBalance: + case eCSE_Feature_Bass: + case eCSE_Feature_Mid: + case eCSE_Feature_Treble: + case eCSE_Feature_GEQ: + case eCSE_Feature_AGC: + case eCSE_Feature_Delay: + case eCSE_Feature_BassBoost: + case eCSE_Feature_Loudness: + default: + bStatus = false; + } + + return bStatus; +} + +FunctionBlockFeature* +FunctionBlockFeature::clone() const +{ + return new FunctionBlockFeature( *this ); +} + +///////////////////////////////// + +FunctionBlockProcessing::FunctionBlockProcessing() + : IBusData() + , m_selectorLength( 0x04 ) + , m_fbInputPlugNumber( 0x00 ) + , m_inputAudioChannelNumber( 0x00 ) + , m_outputAudioChannelNumber( 0x00 ) + , m_pMixer( 0 ) + , m_pEnhancedMixer( 0 ) +{ +} + +FunctionBlockProcessing::FunctionBlockProcessing( const FunctionBlockProcessing& rhs ) + : m_selectorLength( rhs.m_selectorLength ) + , m_fbInputPlugNumber( rhs.m_fbInputPlugNumber ) + , m_inputAudioChannelNumber( rhs.m_inputAudioChannelNumber ) + , m_outputAudioChannelNumber( rhs.m_outputAudioChannelNumber ) +{ + if ( rhs.m_pMixer ) { + m_pMixer = new FunctionBlockProcessingMixer( *rhs.m_pMixer ); + } else if ( rhs.m_pEnhancedMixer ) { + m_pEnhancedMixer = new FunctionBlockProcessingEnhancedMixer( *rhs.m_pEnhancedMixer ); + } +} + +FunctionBlockProcessing::~FunctionBlockProcessing() +{ + delete m_pMixer; + m_pMixer = 0; + delete m_pEnhancedMixer; + m_pEnhancedMixer = 0; +} + +bool +FunctionBlockProcessing::serialize( IOSSerialize& se ) +{ + bool bStatus; + bStatus = se.write( m_selectorLength, "FunctionBlockProcessing selectorLength" ); + bStatus &= se.write( m_fbInputPlugNumber, "FunctionBlockProcessing fbInputPlugNumber" ); + bStatus &= se.write( m_inputAudioChannelNumber, "FunctionBlockProcessing inputAudioChannelNumber" ); + bStatus &= se.write( m_outputAudioChannelNumber, "FunctionBlockProcessing outputAudioChannelNumber" ); + + if ( m_pMixer ) { + bStatus &= m_pMixer->serialize( se ); + } else if ( m_pEnhancedMixer ) { + bStatus &= m_pEnhancedMixer->serialize( se ); + } else { + bStatus = false; + } + + return bStatus; +} + +bool +FunctionBlockProcessing::deserialize( IISDeserialize& de ) +{ + // NOTE: apparently the fbCmd of the STATUS type, + // with EnhancedMixer controlSelector returns with this + // controlSelector type changed to Mixer, making it + // impossible to choose the correct response handler + // based upon the response only. + + // HACK: we assume that it is the same as the sent one + // we also look at our data structure to figure out what we sent + byte_t controlSelector=eCSE_Processing_Unknown; + if(m_pMixer) { + controlSelector=eCSE_Processing_Mixer; + } else if(m_pEnhancedMixer) { + controlSelector=eCSE_Processing_EnhancedMixer; + } + + bool bStatus; + bStatus = de.read( &m_selectorLength ); + bStatus &= de.read( &m_fbInputPlugNumber ); + bStatus &= de.read( &m_inputAudioChannelNumber ); + bStatus &= de.read( &m_outputAudioChannelNumber ); + + byte_t controlSelector_response; + bStatus &= de.peek( &controlSelector_response ); +/* debugOutput(DEBUG_LEVEL_VERBOSE,"ctrlsel: orig = %02X, resp = %02X\n", + controlSelector, controlSelector_response);*/ + + switch( controlSelector ) { + case eCSE_Processing_Mixer: + if ( !m_pMixer ) { + m_pMixer = new FunctionBlockProcessingMixer; + } + bStatus &= m_pMixer->deserialize( de ); + break; + case eCSE_Processing_EnhancedMixer: + if ( !m_pEnhancedMixer ) { + m_pEnhancedMixer = new FunctionBlockProcessingEnhancedMixer; + } + bStatus &= m_pEnhancedMixer->deserialize( de ); + break; + case eCSE_Processing_Enable: + case eCSE_Processing_Mode: + default: + bStatus = false; + } + + byte_t tmp; + if (de.peek(&tmp)) { + debugOutput(DEBUG_LEVEL_VERBOSE,"Unprocessed bytes:\n"); + while (de.read(&tmp)) { + debugOutput(DEBUG_LEVEL_VERBOSE," %02X\n",tmp); + } + } + + return bStatus; +} + +FunctionBlockProcessing* +FunctionBlockProcessing::clone() const +{ + return new FunctionBlockProcessing( *this ); +} + +///////////////////////////////// + +FunctionBlockCodec::FunctionBlockCodec() + : IBusData() +{ +} + +FunctionBlockCodec::FunctionBlockCodec( const FunctionBlockCodec& rhs ) + : IBusData() +{ +} + +FunctionBlockCodec::~FunctionBlockCodec() +{ +} + +bool +FunctionBlockCodec::serialize( IOSSerialize& se ) +{ + return false; +} + +bool +FunctionBlockCodec::deserialize( IISDeserialize& de ) +{ + return false; +} + +FunctionBlockCodec* +FunctionBlockCodec::clone() const +{ + return new FunctionBlockCodec( *this ); +} + +///////////////////////////////// +///////////////////////////////// + +FunctionBlockCmd::FunctionBlockCmd( Ieee1394Service& ieee1394service, + EFunctionBlockType eType, + function_block_id_t id, + EControlAttribute eCtrlAttrib ) + : AVCCommand( ieee1394service, AVC1394_FUNCTION_BLOCK_CMD ) + , m_functionBlockType( eType ) + , m_functionBlockId( id ) + , m_controlAttribute( eCtrlAttrib ) + , m_pFBSelector( 0 ) + , m_pFBFeature( 0 ) + , m_pFBProcessing( 0 ) + , m_pFBCodec( 0 ) +{ + setSubunitType( eST_Audio ); + + switch( m_functionBlockType ) { + case eFBT_Selector: + m_pFBSelector = new FunctionBlockSelector; + break; + case eFBT_Feature: + m_pFBFeature = new FunctionBlockFeature; + break; + case eFBT_Processing: + m_pFBProcessing = new FunctionBlockProcessing; + break; + case eFBT_Codec: + m_pFBCodec = new FunctionBlockCodec; + break; + } +} + +FunctionBlockCmd::FunctionBlockCmd( const FunctionBlockCmd& rhs ) + : AVCCommand( rhs ) + , m_functionBlockType( rhs.m_functionBlockType ) + , m_functionBlockId( rhs.m_functionBlockId ) + , m_controlAttribute( rhs.m_controlAttribute ) + , m_pFBSelector( new FunctionBlockSelector( *rhs.m_pFBSelector ) ) + , m_pFBFeature( new FunctionBlockFeature( *rhs.m_pFBFeature ) ) + , m_pFBProcessing( new FunctionBlockProcessing( *rhs.m_pFBProcessing ) ) + , m_pFBCodec( new FunctionBlockCodec( *rhs.m_pFBCodec ) ) +{ +} + +FunctionBlockCmd::~FunctionBlockCmd() +{ + delete m_pFBSelector; + m_pFBSelector = 0; + delete m_pFBFeature; + m_pFBFeature = 0; + delete m_pFBProcessing; + m_pFBProcessing = 0; + delete m_pFBCodec; + m_pFBCodec = 0; +} + +bool +FunctionBlockCmd::serialize( IOSSerialize& se ) +{ + bool bStatus; + bStatus = AVCCommand::serialize( se ); + bStatus &= se.write( m_functionBlockType, "FunctionBlockCmd functionBlockType" ); + bStatus &= se.write( m_functionBlockId, "FunctionBlockCmd functionBlockId" ); + bStatus &= se.write( m_controlAttribute, "FunctionBlockCmd controlAttribute" ); + + switch( m_functionBlockType ) { + case eFBT_Selector: + if ( m_pFBSelector ) { + bStatus &= m_pFBSelector->serialize( se ); + } else { + bStatus = false; + } + break; + case eFBT_Feature: + if ( m_pFBFeature ) { + bStatus &= m_pFBFeature->serialize( se ); + } else { + bStatus = false; + } + break; + case eFBT_Processing: + if ( m_pFBProcessing ) { + bStatus &= m_pFBProcessing->serialize( se ); + } else { + bStatus = false; + } + break; + case eFBT_Codec: + if ( m_pFBCodec ) { + bStatus &= m_pFBCodec->serialize( se ); + } else { + bStatus = false; + } + break; + default: + bStatus = false; + } + + return bStatus; +} + +bool +FunctionBlockCmd::deserialize( IISDeserialize& de ) +{ + bool bStatus; + bStatus = AVCCommand::deserialize( de ); + + bStatus &= de.read( &m_functionBlockType ); + bStatus &= de.read( &m_functionBlockId ); + bStatus &= de.read( &m_controlAttribute ); + + switch( m_functionBlockType ) { + case eFBT_Selector: + if ( !m_pFBSelector ) { + m_pFBSelector = new FunctionBlockSelector; + } + bStatus &= m_pFBSelector->deserialize( de ); + break; + case eFBT_Feature: + if ( !m_pFBFeature ) { + m_pFBFeature = new FunctionBlockFeature; + } + bStatus &= m_pFBFeature->deserialize( de ); + break; + case eFBT_Processing: + if ( !m_pFBProcessing ) { + m_pFBProcessing = new FunctionBlockProcessing; + } + bStatus &= m_pFBProcessing->deserialize( de ); + break; + case eFBT_Codec: + if ( !m_pFBCodec ) { + m_pFBCodec = new FunctionBlockCodec; + } + bStatus &= m_pFBCodec->deserialize( de ); + break; + default: + bStatus = false; + } + + return bStatus; +} + +FunctionBlockCmd* +FunctionBlockCmd::clone() const +{ + return new FunctionBlockCmd( *this ); +} + +} Index: trunk/libffado/src/libavc/audiosubunit/avc_audiosubunit.h =================================================================== --- trunk/libffado/src/libavc/audiosubunit/avc_audiosubunit.h (revision 508) +++ trunk/libffado/src/libavc/audiosubunit/avc_audiosubunit.h (revision 508) @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2007 by Pieter Palmers + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVC_AUDIOSUBUNIT_H +#define AVC_AUDIOSUBUNIT_H + +#include "debugmodule/debugmodule.h" + +#include "../general/avc_subunit.h" + +#include + +#warning merge with bebob functionblock +#include "bebob/bebob_functionblock.h" +#include "../audiosubunit/avc_function_block.h" + +namespace AVC { + +class Unit; +// ///////////////////////////// + +class SubunitAudio: public Subunit { + public: + SubunitAudio( Unit& avDevice, + subunit_t id ); + SubunitAudio(); + virtual ~SubunitAudio(); + + virtual bool discover(); +// virtual bool discoverConnections(); +// + virtual const char* getName(); +// + BeBoB::FunctionBlockVector getFunctionBlocks() { return m_functions; }; +// +// protected: +// bool discoverFunctionBlocks(); +// bool discoverFunctionBlocksDo( +// ExtendedSubunitInfoCmd::EFunctionBlockType fbType ); +// bool createFunctionBlock( +// ExtendedSubunitInfoCmd::EFunctionBlockType fbType, +// ExtendedSubunitInfoPageData& data ); +// +// FunctionBlock::ESpecialPurpose convertSpecialPurpose( +// function_block_special_purpose_t specialPurpose ); + + virtual bool serializeChild( Glib::ustring basePath, + Util::IOSerialize& ser ) const; + virtual bool deserializeChild( Glib::ustring basePath, + Util::IODeserialize& deser, + Unit& avDevice ); + +protected: + BeBoB::FunctionBlockVector m_functions; +}; + +} + +#endif Index: trunk/libffado/src/libavc/audiosubunit/avc_function_block.h =================================================================== --- trunk/libffado/src/libavc/audiosubunit/avc_function_block.h (revision 503) +++ trunk/libffado/src/libavc/audiosubunit/avc_function_block.h (revision 503) @@ -0,0 +1,280 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVCFUNCTIONBLOCK_H +#define AVCFUNCTIONBLOCK_H + +#include "../general/avc_extended_cmd_generic.h" +#include "../general/avc_generic.h" + +#include +#include +using namespace std; + +namespace AVC { + + +class FunctionBlockFeatureVolume: public IBusData +{ +public: + FunctionBlockFeatureVolume(); + FunctionBlockFeatureVolume( const FunctionBlockFeatureVolume& rhs ); + virtual ~FunctionBlockFeatureVolume(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual FunctionBlockFeatureVolume* clone() const; + + control_data_length_t m_controlDataLength; + u_int16_t m_volume; +}; + +/////////////////////////////////////////// + +class FunctionBlockProcessingMixer: public IBusData +{ +public: + FunctionBlockProcessingMixer(); + FunctionBlockProcessingMixer( const FunctionBlockProcessingMixer& rhs ); + virtual ~FunctionBlockProcessingMixer(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual FunctionBlockProcessingMixer* clone() const; + + control_selector_t m_controlSelector; +}; + +/////////////////////////////////////////// + +class FunctionBlockProcessingEnhancedMixer: public IBusData +{ +public: + enum EStatusSelector { + eSS_ProgramableState = 0x00, + eSS_Level = 0x01, + }; + + FunctionBlockProcessingEnhancedMixer(); + FunctionBlockProcessingEnhancedMixer( + const FunctionBlockProcessingEnhancedMixer& rhs ); + virtual ~FunctionBlockProcessingEnhancedMixer(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual FunctionBlockProcessingEnhancedMixer* clone() const; + + control_selector_t m_controlSelector; + status_selector_t m_statusSelector; + control_data_ext_length_t m_controlDataLength; + vector m_ProgramableStateData; + vector m_LevelData; +}; + +/////////////////////////////////////////// +/////////////////////////////////////////// + +class FunctionBlockSelector: public IBusData +{ +// untested +public: + // Control selector encoding + enum EControlSelectorEncoding { + eCSE_Selector_Unknown = 0x00, + eCSE_Selector_Selector = 0x01, + }; + + FunctionBlockSelector(); + FunctionBlockSelector( const FunctionBlockSelector& rhs ); + virtual ~FunctionBlockSelector(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual FunctionBlockSelector* clone() const; + + selector_length_t m_selectorLength; + input_fb_plug_number_t m_inputFbPlugNumber; + control_selector_t m_controlSelector; +}; + +/////////////////////////////////////////// + +class FunctionBlockFeature: public IBusData +{ +// no complete implementation +public: + // Control selector encoding + enum EControlSelectorEncoding { + eCSE_Feature_Unknown = 0x00, + eCSE_Feature_Mute = 0x01, + eCSE_Feature_Volume = 0x02, + eCSE_Feature_LRBalance = 0x03, + eCSE_Feature_FRBalance = 0x04, + eCSE_Feature_Bass = 0x05, + eCSE_Feature_Mid = 0x06, + eCSE_Feature_Treble = 0x07, + eCSE_Feature_GEQ = 0x08, + eCSE_Feature_AGC = 0x09, + eCSE_Feature_Delay = 0x0a, + eCSE_Feature_BassBoost = 0x0b, + eCSE_Feature_Loudness = 0x0c, + }; + + FunctionBlockFeature(); + FunctionBlockFeature( const FunctionBlockFeature& rhs ); + virtual ~FunctionBlockFeature(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual FunctionBlockFeature* clone() const; + + selector_length_t m_selectorLength; + audio_channel_number_t m_audioChannelNumber; + control_selector_t m_controlSelector; + + FunctionBlockFeatureVolume* m_pVolume; +}; + +/////////////////////////////////////////// + +class FunctionBlockProcessing: public IBusData +{ +// no complete implementation +public: + // Function block selector + enum EProcessingTypeEncoding { + ePTE_Mixer = 0x01, + ePTE_Generic = 0x02, + ePTE_UpDown = 0x03, + ePTE_DolbyProLogic = 0x04, + ePTE_3dStereoExtender = 0x05, + ePTE_Reverberation = 0x06, + ePTE_Chorus = 0x07, + ePTE_DynamicRangeCompression = 0x08, + }; + + // Control selector encoding + enum EControlSelectorEncoding { + eCSE_Processing_Unknown = 0x00, + eCSE_Processing_Enable = 0x01, + eCSE_Processing_Mode = 0x02, + eCSE_Processing_Mixer = 0x03, + eCSE_Processing_EnhancedMixer = 0xf1, + + // lots of definitions missing + + }; + + FunctionBlockProcessing(); + FunctionBlockProcessing( const FunctionBlockProcessing& rhs ); + virtual ~FunctionBlockProcessing(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual FunctionBlockProcessing* clone() const; + + selector_length_t m_selectorLength; + input_fb_plug_number_t m_fbInputPlugNumber; + input_audio_channel_number_t m_inputAudioChannelNumber; + output_audio_channel_number_t m_outputAudioChannelNumber; + + FunctionBlockProcessingMixer* m_pMixer; + FunctionBlockProcessingEnhancedMixer* m_pEnhancedMixer; +}; + +/////////////////////////////////////////// + +class FunctionBlockCodec: public IBusData +{ +// dummy implementation +public: + // CODEC type endcoding + enum ECodecTypeEncoding { + eCTE_Unknown = 0x00, + eCTE_Ac3Decoder = 0x01, + eCTE_MpegDecoder = 0x02, + eCTE_DtsDecoder = 0x03, + }; + + FunctionBlockCodec(); + FunctionBlockCodec( const FunctionBlockCodec& rhs ); + virtual ~FunctionBlockCodec(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual FunctionBlockCodec* clone() const; +}; + +/////////////////////////////////////////// +/////////////////////////////////////////// + +#define AVC1394_FUNCTION_BLOCK_CMD 0xB8 + +class FunctionBlockCmd: public AVCCommand +{ +public: + enum EFunctionBlockType { + eFBT_Selector = 0x80, + eFBT_Feature = 0x81, + eFBT_Processing = 0x82, + eFBT_Codec = 0x83, + }; + + enum EControlAttribute { + eCA_Resolution = 0x01, + eCA_Minimum = 0x02, + eCA_Maximum = 0x03, + eCA_Default = 0x04, + eCA_Duration = 0x08, + eCA_Current = 0x10, + eCA_Move = 0x18, + eCA_Delta = 0x19, + }; + + FunctionBlockCmd( Ieee1394Service& ieee1394service, + EFunctionBlockType eType, + function_block_id_t id, + EControlAttribute eCtrlAttrib ); + FunctionBlockCmd( const FunctionBlockCmd& rhs ); + virtual ~FunctionBlockCmd(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual FunctionBlockCmd* clone() const; + + virtual const char* getCmdName() const + { return "FunctionBlockCmd"; } + + function_block_type_t m_functionBlockType; + function_block_id_t m_functionBlockId; + control_attribute_t m_controlAttribute; + + FunctionBlockSelector* m_pFBSelector; + FunctionBlockFeature* m_pFBFeature; + FunctionBlockProcessing* m_pFBProcessing; + FunctionBlockCodec* m_pFBCodec; +}; + +} + +#endif Index: trunk/libffado/src/libavc/general/avc_plug.cpp =================================================================== --- trunk/libffado/src/libavc/general/avc_plug.cpp (revision 554) +++ trunk/libffado/src/libavc/general/avc_plug.cpp (revision 554) @@ -0,0 +1,2331 @@ +/* + * Copyright (C) 2007 by Pieter Palmers + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_plug.h" +#include "avc_unit.h" +#include "avc_signal_format.h" + +#include "libieee1394/configrom.h" + +#include "libieee1394/ieee1394service.h" +#include "../util/avc_serialize.h" + +#include + +namespace AVC { + +int Plug::m_globalIdCounter = 0; + +IMPL_DEBUG_MODULE( Plug, Plug, DEBUG_LEVEL_NORMAL ); +IMPL_DEBUG_MODULE( PlugManager, PlugManager, DEBUG_LEVEL_NORMAL ); + +Plug::Plug( Unit* unit, + Subunit* subunit, + function_block_type_t functionBlockType, + function_block_id_t functionBlockId, + EPlugAddressType plugAddressType, + EPlugDirection plugDirection, + plug_id_t plugId ) + : m_unit(unit) + , m_subunit(subunit) + , m_functionBlockType( functionBlockType ) + , m_functionBlockId( functionBlockId ) + , m_addressType( plugAddressType ) + , m_direction( plugDirection ) + , m_id( plugId ) + , m_infoPlugType( eAPT_Unknown ) + , m_nrOfChannels( 0 ) + , m_globalId( m_globalIdCounter++ ) +{ + debugOutput( DEBUG_LEVEL_VERBOSE, + "nodeId = %d, subunitType = %d, " + "subunitId = %d, functionBlockType = %d, " + "functionBlockId = %d, addressType = %d, " + "direction = %d, id = %d\n", + m_unit->getConfigRom().getNodeId(), + getSubunitType(), + getSubunitId(), + m_functionBlockType, + m_functionBlockId, + m_addressType, + m_direction, + m_id ); +} + +Plug::Plug( const Plug& rhs ) + : m_unit ( rhs.m_unit ) + , m_subunit ( rhs.m_subunit ) + , m_functionBlockType( rhs.m_functionBlockType ) + , m_functionBlockId( rhs.m_functionBlockId ) + , m_addressType( rhs.m_addressType ) + , m_direction( rhs.m_direction ) + , m_id( rhs.m_id ) + , m_infoPlugType( rhs.m_infoPlugType ) + , m_nrOfChannels( rhs.m_nrOfChannels ) + , m_name( rhs.m_name ) + , m_clusterInfos( rhs.m_clusterInfos ) + , m_formatInfos( rhs.m_formatInfos ) +{ + if ( getDebugLevel() ) { + setDebugLevel( DEBUG_LEVEL_VERBOSE ); + } +} + +Plug::Plug() + : m_unit( NULL ) + , m_subunit( NULL ) + , m_functionBlockType( 0 ) + , m_functionBlockId( 0 ) + , m_addressType( eAPA_Undefined ) + , m_direction( eAPD_Unknown ) + , m_id( 0 ) + , m_infoPlugType( eAPT_Unknown ) + , m_nrOfChannels( 0 ) + , m_globalId( 0 ) +{ +} + +Plug::~Plug() +{ + m_unit->getPlugManager().remPlug( *this ); +} + +ESubunitType +Plug::getSubunitType() const +{ + return (m_subunit==NULL?eST_Unit:m_subunit->getSubunitType()); +} + +subunit_id_t +Plug::getSubunitId() const +{ + return (m_subunit==NULL?0xFF:m_subunit->getSubunitId()); +} + +bool +Plug::discover() +{ + + if ( !initFromDescriptor() ) { + debugError( "discover: Could not init plug from descriptor (%d,%d,%d,%d,%d)\n", + m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id ); +// return false; + } + + if ( !discoverPlugType() ) { + debugError( "discover: Could not discover plug type (%d,%d,%d,%d,%d)\n", + m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id ); + return false; + } + + if ( !discoverName() ) { + debugError( "Could not discover name (%d,%d,%d,%d,%d)\n", + m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id ); + return false; + } + + if ( !discoverNoOfChannels() ) { + debugError( "Could not discover number of channels " + "(%d,%d,%d,%d,%d)\n", + m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id ); + return false; + } + + if ( !discoverChannelPosition() ) { + debugError( "Could not discover channel positions " + "(%d,%d,%d,%d,%d)\n", + m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id ); + return false; + } + + if ( !discoverChannelName() ) { + debugError( "Could not discover channel name " + "(%d,%d,%d,%d,%d)\n", + m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id ); + return false; + } + + if ( !discoverClusterInfo() ) { + debugError( "Could not discover channel name " + "(%d,%d,%d,%d,%d)\n", + m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id ); + return false; + } + + if ( !discoverStreamFormat() ) { + debugError( "Could not discover stream format " + "(%d,%d,%d,%d,%d)\n", + m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id ); +// return false; + } + + if ( !discoverSupportedStreamFormats() ) { + debugError( "Could not discover supported stream formats " + "(%d,%d,%d,%d,%d)\n", + m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id ); +// return false; + } + + return m_unit->getPlugManager().addPlug( *this ); +} + +bool +Plug::initFromDescriptor() +{ + if(getSubunitType()==eST_Unit) { + debugOutput(DEBUG_LEVEL_VERBOSE, "Not loading unit plug from descriptor.\n"); + return true; + } else { + return m_subunit->initPlugFromDescriptor(*this); + } +} + +bool +Plug::discoverConnections() +{ + return discoverConnectionsInput() && discoverConnectionsOutput(); +} + +bool +Plug::discoverPlugType() +{ + + return true; +} + +bool +Plug::discoverName() +{ + // name already set + if (m_name != "") return true; + + m_name = plugAddressTypeToString(getPlugAddressType()); + m_name += " "; + m_name += plugTypeToString(getPlugType()); + m_name += " "; + m_name += plugDirectionToString(getPlugDirection()); + + return true; +} + +bool +Plug::discoverNoOfChannels() +{ + + return true; +} + +bool +Plug::discoverChannelPosition() +{ + + return true; +} + +bool +Plug::discoverChannelName() +{ + + return true; +} + +bool +Plug::discoverClusterInfo() +{ + + return true; +} + +bool +Plug::discoverStreamFormat() +{ + ExtendedStreamFormatCmd extStreamFormatCmd = + setPlugAddrToStreamFormatCmd( ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommand ); + extStreamFormatCmd.setVerbose( getDebugLevel() ); + + if ( !extStreamFormatCmd.fire() ) { + debugError( "stream format command failed\n" ); + return false; + } + + if ( ( extStreamFormatCmd.getStatus() == ExtendedStreamFormatCmd::eS_NoStreamFormat ) + || ( extStreamFormatCmd.getStatus() == ExtendedStreamFormatCmd::eS_NotUsed ) ) + { + debugOutput( DEBUG_LEVEL_VERBOSE, + "No stream format information available\n" ); + return true; + } + + if ( !extStreamFormatCmd.getFormatInformation() ) { + debugWarning( "No stream format information for plug found -> skip\n" ); + return true; + } + + if ( extStreamFormatCmd.getFormatInformation()->m_root + != FormatInformation::eFHR_AudioMusic ) + { + debugWarning( "Format hierarchy root is not Audio&Music -> skip\n" ); + return true; + } + + FormatInformation* formatInfo = + extStreamFormatCmd.getFormatInformation(); + FormatInformationStreamsCompound* compoundStream + = dynamic_cast< FormatInformationStreamsCompound* > ( + formatInfo->m_streams ); + if ( compoundStream ) { + m_samplingFrequency = + compoundStream->m_samplingFrequency; + debugOutput( DEBUG_LEVEL_VERBOSE, + "%s plug %d uses " + "sampling frequency %d, nr of stream infos = %d\n", + getName(), + m_id, + m_samplingFrequency, + compoundStream->m_numberOfStreamFormatInfos ); + + for ( int i = 1; + i <= compoundStream->m_numberOfStreamFormatInfos; + ++i ) + { + ClusterInfo* clusterInfo = + const_cast( getClusterInfoByIndex( i ) ); + + if ( !clusterInfo ) { + debugError( "No matching cluster " + "info found for index %d\n", i ); + return false; + } + StreamFormatInfo* streamFormatInfo = + compoundStream->m_streamFormatInfos[ i - 1 ]; + + debugOutput( DEBUG_LEVEL_VERBOSE, + "number of channels = %d, stream format = %d\n", + streamFormatInfo->m_numberOfChannels, + streamFormatInfo->m_streamFormat ); + + int nrOfChannels = clusterInfo->m_nrOfChannels; + if ( streamFormatInfo->m_streamFormat == + FormatInformation::eFHL2_AM824_MIDI_CONFORMANT ) + { + // 8 logical midi channels fit into 1 channel + nrOfChannels = ( ( nrOfChannels + 7 ) / 8 ); + } + // sanity check + if ( nrOfChannels != streamFormatInfo->m_numberOfChannels ) + { + debugWarning( "Number of channels " + "mismatch: '%s' plug discovering reported " + "%d channels for cluster '%s', while stream " + "format reported %d\n", + getName(), + nrOfChannels, + clusterInfo->m_name.c_str(), + streamFormatInfo->m_numberOfChannels); + } + clusterInfo->m_streamFormat = streamFormatInfo->m_streamFormat; + + debugOutput( DEBUG_LEVEL_VERBOSE, + "%s plug %d cluster info %d ('%s'): " + "stream format %d\n", + getName(), + m_id, + i, + clusterInfo->m_name.c_str(), + clusterInfo->m_streamFormat ); + } + } + + FormatInformationStreamsSync* syncStream + = dynamic_cast< FormatInformationStreamsSync* > ( + formatInfo->m_streams ); + if ( syncStream ) { + m_samplingFrequency = + syncStream->m_samplingFrequency; + debugOutput( DEBUG_LEVEL_VERBOSE, + "%s plug %d is sync stream with sampling frequency %d\n", + getName(), + m_id, + m_samplingFrequency ); + } + + + if ( !compoundStream && !syncStream ) + { + debugError( "Unsupported stream format\n" ); + return false; + } + + return true; +} + +bool +Plug::discoverSupportedStreamFormats() +{ + ExtendedStreamFormatCmd extStreamFormatCmd = + setPlugAddrToStreamFormatCmd( + ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommandList); + extStreamFormatCmd.setVerbose( getDebugLevel() ); + + int i = 0; + bool cmdSuccess = false; + + do { + extStreamFormatCmd.setIndexInStreamFormat( i ); + extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status ); + cmdSuccess = extStreamFormatCmd.fire(); + if ( cmdSuccess + && ( extStreamFormatCmd.getResponse() + == AVCCommand::eR_Implemented ) ) + { + FormatInfo formatInfo; + formatInfo.m_index = i; + bool formatInfoIsValid = true; + + FormatInformationStreamsSync* syncStream + = dynamic_cast< FormatInformationStreamsSync* > + ( extStreamFormatCmd.getFormatInformation()->m_streams ); + if ( syncStream ) { + formatInfo.m_samplingFrequency = + syncStream->m_samplingFrequency; + formatInfo.m_isSyncStream = true ; + } + + FormatInformationStreamsCompound* compoundStream + = dynamic_cast< FormatInformationStreamsCompound* > + ( extStreamFormatCmd.getFormatInformation()->m_streams ); + if ( compoundStream ) { + formatInfo.m_samplingFrequency = + compoundStream->m_samplingFrequency; + formatInfo.m_isSyncStream = false; + for ( int j = 0; + j < compoundStream->m_numberOfStreamFormatInfos; + ++j ) + { + switch ( compoundStream->m_streamFormatInfos[j]->m_streamFormat ) { + case AVC1394_STREAM_FORMAT_AM824_IEC60968_3: + formatInfo.m_audioChannels += + compoundStream->m_streamFormatInfos[j]->m_numberOfChannels; + break; + case AVC1394_STREAM_FORMAT_AM824_MULTI_BIT_LINEAR_AUDIO_RAW: + formatInfo.m_audioChannels += + compoundStream->m_streamFormatInfos[j]->m_numberOfChannels; + break; + case AVC1394_STREAM_FORMAT_AM824_MIDI_CONFORMANT: + formatInfo.m_midiChannels += + compoundStream->m_streamFormatInfos[j]->m_numberOfChannels; + break; + default: + formatInfoIsValid = false; + debugWarning("unknown stream format (0x%02x) for channel " + "(%d)\n", + compoundStream->m_streamFormatInfos[j]->m_streamFormat, + j ); + } + } + } + + if ( formatInfoIsValid ) { + flushDebugOutput(); + debugOutput( DEBUG_LEVEL_VERBOSE, + "[%s:%d] formatInfo[%d].m_samplingFrequency " + "= %d\n", + getName(), m_id, + i, formatInfo.m_samplingFrequency ); + debugOutput( DEBUG_LEVEL_VERBOSE, + "[%s:%d] formatInfo[%d].m_isSyncStream = %d\n", + getName(), m_id, + i, formatInfo.m_isSyncStream ); + debugOutput( DEBUG_LEVEL_VERBOSE, + "[%s:%d] formatInfo[%d].m_audioChannels = %d\n", + getName(), m_id, + i, formatInfo.m_audioChannels ); + debugOutput( DEBUG_LEVEL_VERBOSE, + "[%s:%d] formatInfo[%d].m_midiChannels = %d\n", + getName(), m_id, + i, formatInfo.m_midiChannels ); + m_formatInfos.push_back( formatInfo ); + flushDebugOutput(); + } + } + + ++i; + } while ( cmdSuccess && ( extStreamFormatCmd.getResponse() + == ExtendedStreamFormatCmd::eR_Implemented ) ); + + return true; +} + +bool +Plug::discoverConnectionsInput() +{ + debugOutput( DEBUG_LEVEL_VERBOSE, "Discovering incoming connections...\n"); + + int sourcePlugGlobalId=getSignalSource(); + + if(sourcePlugGlobalId >= 0) { + Plug *p=m_unit->getPlugManager().getPlug(sourcePlugGlobalId); + if (p==NULL) { + debugError( "Plug with global id %d not found\n",sourcePlugGlobalId ); + return false; + } + // connected to another plug + debugOutput( DEBUG_LEVEL_VERBOSE, "Plug '%s' gets signal from '%s'...\n", + getName(), p->getName() ); + + + + if ( p ) { + debugOutput( DEBUG_LEVEL_VERBOSE, + "'(%d) %s' has a connection to '(%d) %s'\n", + getGlobalId(), + getName(), + p->getGlobalId(), + p->getName() ); + addPlugConnection( m_inputConnections, *p ); + } else { + debugError( "no corresponding plug found for '(%d) %s'\n", + getGlobalId(), + getName() ); + return false; + } + + } + + return true; +} + +bool +Plug::discoverConnectionsOutput() +{ + return true; +} + +bool +Plug::inquireConnnection( Plug& plug ) +{ + SignalSourceCmd signalSourceCmd = setSrcPlugAddrToSignalCmd(); + setDestPlugAddrToSignalCmd( signalSourceCmd, plug ); + signalSourceCmd.setCommandType( AVCCommand::eCT_SpecificInquiry ); + signalSourceCmd.setVerbose( getDebugLevel() ); + + if ( !signalSourceCmd.fire() ) { + debugError( "Could not inquire connection between '%s' and '%s'\n", + getName(), plug.getName() ); + return false; + } + + if ( signalSourceCmd.getResponse() == AVCCommand::eR_Implemented ) { + debugOutput( DEBUG_LEVEL_VERBOSE, + "Connection possible between '%s' and '%s'\n", + getName(), plug.getName() ); + return true; + } + debugOutput( DEBUG_LEVEL_VERBOSE, + "Connection not possible between '%s' and '%s'\n", + getName(), plug.getName() ); + return false; +} + +int +Plug::getSignalSource() +{ + if((getPlugAddressType() == eAPA_PCR) || + (getPlugAddressType() == eAPA_ExternalPlug)) { + if (getPlugDirection() != eAPD_Output) { + debugWarning("Signal Source command not valid for non-output unit plugs...\n"); + return -1; + } + } + + if(getPlugAddressType() == eAPA_SubunitPlug) { + if (getPlugDirection() != eAPD_Input) { + debugWarning("Signal Source command not valid for non-input subunit plugs...\n"); + return -1; + } + } + + SignalSourceCmd signalSourceCmd( m_unit->get1394Service() ); + + signalSourceCmd.setNodeId( m_unit->getConfigRom().getNodeId() ); + signalSourceCmd.setSubunitType( eST_Unit ); + signalSourceCmd.setSubunitId( 0xff ); + + SignalSubunitAddress signalSubunitAddr; + signalSubunitAddr.m_subunitType = 0xFF; + signalSubunitAddr.m_subunitId = 0xFF; + signalSubunitAddr.m_plugId = 0xFE; + signalSourceCmd.setSignalSource( signalSubunitAddr ); + + setDestPlugAddrToSignalCmd( signalSourceCmd, *this ); + + signalSourceCmd.setCommandType( AVCCommand::eCT_Status ); + signalSourceCmd.setVerbose( getDebugLevel() ); + signalSourceCmd.setVerbose( DEBUG_LEVEL_VERY_VERBOSE ); + + if ( !signalSourceCmd.fire() ) { + debugError( "Could not get signal source for '%s'\n", + getName() ); + return -1; + } + + if ( signalSourceCmd.getResponse() == AVCCommand::eR_Implemented ) { + SignalAddress* src=signalSourceCmd.getSignalSource(); + Plug* p=NULL; + if(dynamic_cast(src)) { + SignalUnitAddress *usrc=dynamic_cast(src); + if (usrc->m_plugId & 0x80) { + p=m_unit->getPlugManager().getPlug( eST_Unit, 0xFF, + 0xFF, 0xFF, eAPA_ExternalPlug, eAPD_Input, + usrc->m_plugId & 0x7F ); + } else { + p=m_unit->getPlugManager().getPlug( eST_Unit, 0xFF, + 0xFF, 0xFF, eAPA_PCR, eAPD_Input, + usrc->m_plugId & 0x7F ); + } + } else if (dynamic_cast(src)) { + SignalSubunitAddress *susrc=dynamic_cast(src); + p=m_unit->getPlugManager().getPlug( byteToSubunitType(susrc->m_subunitType), + susrc->m_subunitId, 0xFF, 0xFF, eAPA_SubunitPlug, + eAPD_Output, susrc->m_plugId); + } else return -1; + + if (p==NULL) { + debugError("reported signal source plug not found\n"); + return -1; + } + + return p->getGlobalId(); + } + + return -1; +} + +bool +Plug::setConnection( Plug& plug ) +{ + SignalSourceCmd signalSourceCmd = setSrcPlugAddrToSignalCmd(); + setDestPlugAddrToSignalCmd( signalSourceCmd, plug ); + signalSourceCmd.setCommandType( AVCCommand::eCT_Control ); + signalSourceCmd.setVerbose( getDebugLevel() ); + + if ( !signalSourceCmd.fire() ) { + debugError( "Could not set connection between '%s' and '%s'\n", + getName(), plug.getName() ); + return false; + } + + if ( signalSourceCmd.getResponse() == AVCCommand::eR_Accepted ) { + debugOutput( DEBUG_LEVEL_VERBOSE, + "Could set connection between '%s' and '%s'\n", + getName(), plug.getName() ); + return true; + } + debugOutput( DEBUG_LEVEL_VERBOSE, + "Could not set connection between '%s' and '%s'\n", + getName(), plug.getName() ); + return false; +} + +bool +Plug::propagateFromConnectedPlug( ) { + + if (getDirection() == eAPD_Output) { + if (getInputConnections().size()==0) { + debugWarning("No input connections to propagate from, skipping.\n"); + return true; + } + if (getInputConnections().size()>1) { + debugWarning("Too many input connections to propagate from, using first one.\n"); + } + + Plug* p = *(getInputConnections().begin()); + return propagateFromPlug( p ); + + } else if (getDirection() == eAPD_Input) { + if (getOutputConnections().size()==0) { + debugWarning("No output connections to propagate from, skipping.\n"); + return true; + } + if (getOutputConnections().size()>1) { + debugWarning("Too many output connections to propagate from, using first one.\n"); + } + + Plug* p = *(getOutputConnections().begin()); + return propagateFromPlug( p ); + + } else { + debugWarning("plug with undefined direction\n"); + return false; + } +} + +bool +Plug::propagateFromPlug( Plug *p ) { + debugOutput( DEBUG_LEVEL_VERBOSE, + "Propagating info from plug '%s' to plug '%s'\n", + p->getName(), getName() ); + + if (m_clusterInfos.size()==0) { + m_clusterInfos=p->m_clusterInfos; + } + + m_nrOfChannels=p->m_nrOfChannels; + + return true; +} + +int +Plug::getNrOfStreams() const +{ + int nrOfChannels = 0; + for ( ClusterInfoVector::const_iterator it = m_clusterInfos.begin(); + it != m_clusterInfos.end(); + ++it ) + { + const ClusterInfo* clusterInfo = &( *it ); + nrOfChannels += clusterInfo->m_nrOfChannels; + } + return nrOfChannels; +} + +int +Plug::getNrOfChannels() const +{ + return m_nrOfChannels; +} + +bool +Plug::setNrOfChannels(int i) +{ + m_nrOfChannels=i; + return true; +} + +int +Plug::getSampleRate() const +{ + if(getPlugAddressType()==eAPA_PCR) { + if(getPlugDirection()==eAPD_Input) { + InputPlugSignalFormatCmd cmd( m_unit->get1394Service() ); + cmd.m_form=0xFF; + cmd.m_eoh=0xFF; + cmd.m_fmt=0xFF; + cmd.m_plug=getPlugId(); + + cmd.setNodeId( m_unit->getConfigRom().getNodeId() ); + cmd.setSubunitType( eST_Unit ); + cmd.setSubunitId( 0xff ); + + cmd.setCommandType( AVCCommand::eCT_Status ); + + if ( !cmd.fire() ) { + debugError( "input plug signal format command failed\n" ); + return 0; + } + + if (cmd.m_fmt != 0x10 ) { + debugWarning("Incorrect FMT response received: 0x%02X\n",cmd.m_fmt); + } + + return fdfSfcToSampleRate(cmd.m_fdf[0]); + + } else if (getPlugDirection()==eAPD_Output) { + OutputPlugSignalFormatCmd cmd( m_unit->get1394Service() ); + cmd.m_form=0xFF; + cmd.m_eoh=0xFF; + cmd.m_fmt=0xFF; + cmd.m_plug=getPlugId(); + + cmd.setNodeId( m_unit->getConfigRom().getNodeId() ); + cmd.setSubunitType( eST_Unit ); + cmd.setSubunitId( 0xff ); + + cmd.setCommandType( AVCCommand::eCT_Status ); + + if ( !cmd.fire() ) { + debugError( "output plug signal format command failed\n" ); + return 0; + } + + if (cmd.m_fmt != 0x10 ) { + debugWarning("Incorrect FMT response received: 0x%02X\n",cmd.m_fmt); + } + + return fdfSfcToSampleRate(cmd.m_fdf[0]); + + } else { + debugError("PCR plug with undefined direction.\n"); + return 0; + } + } + + // fallback + return convertESamplingFrequency( static_cast( m_samplingFrequency ) ); +} + +bool +Plug::setSampleRate( int rate ) +{ + // apple style + if(getPlugAddressType()==eAPA_PCR) { + if(getPlugDirection()==eAPD_Input) { + InputPlugSignalFormatCmd cmd( m_unit->get1394Service() ); + cmd.m_eoh=1; + cmd.m_form=0; + cmd.m_fmt=0x10; + cmd.m_plug=getPlugId(); + cmd.m_fdf[0]=sampleRateToFdfSfc(rate); + cmd.m_fdf[1]=0xFF; + cmd.m_fdf[2]=0xFF; + + cmd.setNodeId( m_unit->getConfigRom().getNodeId() ); + cmd.setSubunitType( eST_Unit ); + cmd.setSubunitId( 0xff ); + + cmd.setCommandType( AVCCommand::eCT_Control ); + + if ( !cmd.fire() ) { + debugError( "input plug signal format command failed\n" ); + return false; + } + + if ( cmd.getResponse() == AVCCommand::eR_Accepted ) + { + return true; + } + debugWarning( "output plug signal format command not accepted\n" ); + + } else if (getPlugDirection()==eAPD_Output) { + OutputPlugSignalFormatCmd cmd( m_unit->get1394Service() ); + cmd.m_eoh=1; + cmd.m_form=0; + cmd.m_fmt=0x10; + cmd.m_plug=getPlugId(); + cmd.m_fdf[0]=sampleRateToFdfSfc(rate); + cmd.m_fdf[1]=0xFF; + cmd.m_fdf[2]=0xFF; + + cmd.setNodeId( m_unit->getConfigRom().getNodeId() ); + cmd.setSubunitType( eST_Unit ); + cmd.setSubunitId( 0xff ); + + cmd.setCommandType( AVCCommand::eCT_Control ); + + if ( !cmd.fire() ) { + debugError( "output plug signal format command failed\n" ); + return false; + } + + if ( cmd.getResponse() == AVCCommand::eR_Accepted ) + { + return true; + } + debugWarning( "output plug signal format command not accepted\n" ); + } else { + debugError("PCR plug with undefined direction.\n"); + return false; + } + } + + // fallback: BeBoB style + ESamplingFrequency samplingFrequency = parseSampleRate(rate); + + ExtendedStreamFormatCmd extStreamFormatCmd( + m_unit->get1394Service(), + ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommandList ); + UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, + getPlugId() ); + + extStreamFormatCmd.setPlugAddress( + PlugAddress( + Plug::convertPlugDirection(getPlugDirection() ), + PlugAddress::ePAM_Unit, + unitPlugAddress ) ); + + extStreamFormatCmd.setNodeId( m_unit->getConfigRom().getNodeId() ); + extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status ); + + int i = 0; + bool cmdSuccess = false; + bool correctFormatFound = false; + + do { + extStreamFormatCmd.setIndexInStreamFormat( i ); + extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status ); + extStreamFormatCmd.setVerbose( getDebugLevel() ); + + cmdSuccess = extStreamFormatCmd.fire(); + + if ( cmdSuccess + && ( extStreamFormatCmd.getResponse() == + AVCCommand::eR_Implemented ) ) + { + ESamplingFrequency foundFreq = eSF_DontCare; + + FormatInformation* formatInfo = + extStreamFormatCmd.getFormatInformation(); + FormatInformationStreamsCompound* compoundStream + = dynamic_cast< FormatInformationStreamsCompound* > ( + formatInfo->m_streams ); + if ( compoundStream ) { + foundFreq = + static_cast< ESamplingFrequency >( + compoundStream->m_samplingFrequency ); + } + + FormatInformationStreamsSync* syncStream + = dynamic_cast< FormatInformationStreamsSync* > ( + formatInfo->m_streams ); + if ( syncStream ) { + foundFreq = + static_cast< ESamplingFrequency >( + syncStream->m_samplingFrequency ); + } + + if ( foundFreq == samplingFrequency ) + { + correctFormatFound = true; + break; + } + } + + ++i; + } while ( cmdSuccess + && ( extStreamFormatCmd.getResponse() == + ExtendedStreamFormatCmd::eR_Implemented ) ); + + if ( !cmdSuccess ) { + debugError( "setSampleRatePlug: Failed to retrieve format info\n" ); + return false; + } + + if ( !correctFormatFound ) { + debugError( "setSampleRatePlug: %s plug %d does not support " + "sample rate %d\n", + getName(), + getPlugId(), + convertESamplingFrequency( samplingFrequency ) ); + return false; + } + + extStreamFormatCmd.setSubFunction( + ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommand ); + extStreamFormatCmd.setCommandType( AVCCommand::eCT_Control ); + extStreamFormatCmd.setVerbose( getDebugLevel() ); + + if ( !extStreamFormatCmd.fire() ) { + debugError( "setSampleRate: Could not set sample rate %d " + "to %s plug %d\n", + convertESamplingFrequency( samplingFrequency ), + getName(), + getPlugId() ); + return false; + } + + return true; +} + +bool +Plug::discoverConnectionsFromSpecificData( + EPlugDirection discoverDirection, + PlugAddressSpecificData* plugAddress, + PlugVector& connections ) +{ + UnitPlugSpecificDataPlugAddress* pUnitPlugAddress = + dynamic_cast + ( plugAddress->m_plugAddressData ); + + SubunitPlugSpecificDataPlugAddress* pSubunitPlugAddress = + dynamic_cast + ( plugAddress->m_plugAddressData ); + + FunctionBlockPlugSpecificDataPlugAddress* + pFunctionBlockPlugAddress = + dynamic_cast + ( plugAddress->m_plugAddressData ); + + Plug* plug = getPlugDefinedBySpecificData( + pUnitPlugAddress, + pSubunitPlugAddress, + pFunctionBlockPlugAddress ); + + if ( plug ) { + debugOutput( DEBUG_LEVEL_VERBOSE, + "'(%d) %s' has a connection to '(%d) %s'\n", + getGlobalId(), + getName(), + plug->getGlobalId(), + plug->getName() ); + addPlugConnection( connections, *plug ); + } else { + debugError( "no corresponding plug found for '(%d) %s'\n", + getGlobalId(), + getName() ); + return false; + } + + return true; +} + +bool +Plug::addPlugConnection( PlugVector& connections, + Plug& plug ) + +{ + for ( PlugVector::iterator it = connections.begin(); + it != connections.end(); + ++it ) + { + Plug* cPlug = *it; + if ( cPlug == &plug ) { + debugOutput( DEBUG_LEVEL_VERBOSE, + "plug '%s' already in connection list\n", + plug.getName() ); + return true; + } + } + + connections.push_back( &plug ); + return true; +} + +SignalSourceCmd +Plug::setSrcPlugAddrToSignalCmd() +{ + SignalSourceCmd signalSourceCmd( m_unit->get1394Service() ); + + switch( getSubunitType() ) { + case eST_Unit: + { + SignalUnitAddress signalUnitAddr; + if ( getPlugAddressType() == eAPA_ExternalPlug ) { + signalUnitAddr.m_plugId = m_id + 0x80; + } else { + signalUnitAddr.m_plugId = m_id; + } + signalSourceCmd.setSignalSource( signalUnitAddr ); + } + break; + case eST_Music: + case eST_Audio: + { + SignalSubunitAddress signalSubunitAddr; + signalSubunitAddr.m_subunitType = getSubunitType(); + signalSubunitAddr.m_subunitId = getSubunitId(); + signalSubunitAddr.m_plugId = m_id; + signalSourceCmd.setSignalSource( signalSubunitAddr ); + } + break; + default: + debugError( "Unknown subunit type\n" ); + } + + signalSourceCmd.setNodeId( m_unit->getConfigRom().getNodeId() ); + signalSourceCmd.setSubunitType( eST_Unit ); + signalSourceCmd.setSubunitId( 0xff ); + + return signalSourceCmd; +} + +void +Plug::setDestPlugAddrToSignalCmd(SignalSourceCmd& signalSourceCmd, + Plug& plug) +{ + switch( plug.getSubunitType() ) { + case eST_Unit: + { + SignalUnitAddress signalUnitAddr; + if ( plug.getPlugAddressType() == eAPA_ExternalPlug ) { + signalUnitAddr.m_plugId = plug.m_id + 0x80; + } else { + signalUnitAddr.m_plugId = plug.m_id; + } + signalSourceCmd.setSignalDestination( signalUnitAddr ); + } + break; + case eST_Music: + case eST_Audio: + { + SignalSubunitAddress signalSubunitAddr; + signalSubunitAddr.m_subunitType = plug.getSubunitType(); + signalSubunitAddr.m_subunitId = plug.getSubunitId(); + signalSubunitAddr.m_plugId = plug.m_id; + signalSourceCmd.setSignalDestination( signalSubunitAddr ); + } + break; + default: + debugError( "Unknown subunit type\n" ); + } +} + +void +Plug::debugOutputClusterInfos( int debugLevel ) +{ + for ( ClusterInfoVector::const_iterator it = m_clusterInfos.begin(); + it != m_clusterInfos.end(); + ++it ) + { + const ClusterInfo* clusterInfo = &( *it ); + + debugOutput( debugLevel, "number of channels: %d\n", + clusterInfo->m_nrOfChannels ); + + for ( ChannelInfoVector::const_iterator cit + = clusterInfo->m_channelInfos.begin(); + cit != clusterInfo->m_channelInfos.end(); + ++cit ) + { + const ChannelInfo* channelInfo = &( *cit ); + channelInfo = channelInfo; + debugOutput( debugLevel, + "stream position: %d\n", + channelInfo->m_streamPosition ); + debugOutput( debugLevel, + "location: %d\n", + channelInfo->m_location ); + } + } +} + +const Plug::ClusterInfo* +Plug::getClusterInfoByIndex(int index) const +{ + for ( Plug::ClusterInfoVector::const_iterator clit = + m_clusterInfos.begin(); + clit != m_clusterInfos.end(); + ++clit ) + { + const ClusterInfo* info = &*clit; + if ( info->m_index == index ) { + return info; + } + } + return 0; +} + +PlugAddress::EPlugDirection +Plug::convertPlugDirection( EPlugDirection direction ) +{ + PlugAddress::EPlugDirection dir; + switch ( direction ) { + case Plug::eAPD_Input: + dir = PlugAddress::ePD_Input; + break; + case Plug::eAPD_Output: + dir = PlugAddress::ePD_Output; + break; + default: + dir = PlugAddress::ePD_Undefined; + } + return dir; +} + +std::string +Plug::plugAddressTypeToString(enum EPlugAddressType t) { + switch (t) { + case eAPA_PCR: + return string("PCR"); + case eAPA_ExternalPlug: + return string("External"); + case eAPA_AsynchronousPlug: + return string("Async"); + case eAPA_SubunitPlug: + return string("Subunit"); + case eAPA_FunctionBlockPlug: + return string("Function Block"); + default: + case eAPA_Undefined: + return string("Undefined"); + } +} + +std::string +Plug::plugTypeToString(enum EPlugType t) { + switch (t) { + case eAPT_IsoStream: + return string("IsoStream"); + case eAPT_AsyncStream: + return string("AsyncStream"); + case eAPT_Midi: + return string("MIDI"); + case eAPT_Sync: + return string("Sync"); + case eAPT_Analog: + return string("Analog"); + case eAPT_Digital: + return string("Digital"); + default: + case eAPT_Unknown: + return string("Unknown"); + } +} + +std::string +Plug::plugDirectionToString(enum EPlugDirection t) { + switch (t) { + case eAPD_Input: + return string("Input"); + case eAPD_Output: + return string("Output"); + default: + case eAPT_Unknown: + return string("Unknown"); + } +} + +void +Plug::showPlug() const +{ + debugOutput( DEBUG_LEVEL_VERBOSE, "\tName = %s\n", + getName() ); + debugOutput( DEBUG_LEVEL_VERBOSE, "\tType = %s\n", + extendedPlugInfoPlugTypeToString( getPlugType() ) ); + debugOutput( DEBUG_LEVEL_VERBOSE, "\tAddress Type = %s\n", + avPlugAddressTypeToString( getPlugAddressType() ) ); + debugOutput( DEBUG_LEVEL_VERBOSE, "\tId = %d\n", + getPlugId() ); + debugOutput( DEBUG_LEVEL_VERBOSE, "\tSubunitType = %d\n", + getSubunitType() ); + debugOutput( DEBUG_LEVEL_VERBOSE, "\tSubunitId = %d\n", + getSubunitId() ); + debugOutput( DEBUG_LEVEL_VERBOSE, "\tDirection = %s\n", + avPlugDirectionToString( getPlugDirection() ) ); + debugOutput( DEBUG_LEVEL_VERBOSE, "\tSampling Rate = %d\n", + getSampleRate() ); + debugOutput( DEBUG_LEVEL_VERBOSE, "\tNumber of Channels = %d\n", + getNrOfChannels() ); + debugOutput( DEBUG_LEVEL_VERBOSE, "\tNumber of Streams = %d\n", + getNrOfStreams() ); + debugOutput( DEBUG_LEVEL_VERBOSE, "\tIncoming connections from: "); + + for ( PlugVector::const_iterator it = m_inputConnections.begin(); + it != m_inputConnections.end(); + ++it ) + { + debugOutputShort(DEBUG_LEVEL_VERBOSE, "%s, ", (*it)->getName()); + } + debugOutputShort(DEBUG_LEVEL_VERBOSE, "\n"); + + debugOutput( DEBUG_LEVEL_VERBOSE, "\tOutgoing connections to: "); + for ( PlugVector::const_iterator it = m_outputConnections.begin(); + it != m_outputConnections.end(); + ++it ) + { + debugOutputShort(DEBUG_LEVEL_VERBOSE, "%s, ", (*it)->getName()); + } + debugOutputShort(DEBUG_LEVEL_VERBOSE, "\n"); + + flushDebugOutput(); +} + + +Plug* +Plug::getPlugDefinedBySpecificData( + UnitPlugSpecificDataPlugAddress* pUnitPlugAddress, + SubunitPlugSpecificDataPlugAddress* pSubunitPlugAddress, + FunctionBlockPlugSpecificDataPlugAddress* pFunctionBlockPlugAddress ) +{ + subunit_type_t subunitType = 0xff; + subunit_id_t subunitId = 0xff; + function_block_type_t functionBlockType = 0xff; + function_block_id_t functionBlockId = 0xff; + EPlugAddressType addressType = eAPA_Undefined; + EPlugDirection direction = eAPD_Unknown; + plug_id_t plugId = 0xff; + + if ( !pUnitPlugAddress + && !pSubunitPlugAddress + && !pFunctionBlockPlugAddress ) + { + debugError( "No correct specific data found\n" ); + return 0; + } + + if ( pUnitPlugAddress ) { + subunitType = eST_Unit; + switch ( pUnitPlugAddress->m_plugType ) { + case UnitPlugSpecificDataPlugAddress::ePT_PCR: + addressType = eAPA_PCR; + break; + case UnitPlugSpecificDataPlugAddress::ePT_ExternalPlug: + addressType = eAPA_ExternalPlug; + break; + case UnitPlugSpecificDataPlugAddress::ePT_AsynchronousPlug: + addressType = eAPA_AsynchronousPlug; + break; + } + // unit plug have only connections to subunits + if ( getPlugAddressType() == eAPA_SubunitPlug ) { + direction = getDirection(); + } else { + debugError( "Function block has connection from/to unknown " + "plug type\n" ); + direction = eAPD_Unknown; + } + plugId = pUnitPlugAddress->m_plugId; + + debugOutput( DEBUG_LEVEL_VERBOSE, + "'(%d) %s': Remote plug is a unit plug " + "(%s, %s, %d)\n", + getGlobalId(), + getName(), + avPlugAddressTypeToString( addressType ), + avPlugDirectionToString( direction ), + plugId ); + } + + if ( pSubunitPlugAddress ) { + subunitType = pSubunitPlugAddress->m_subunitType; + subunitId = pSubunitPlugAddress->m_subunitId; + addressType = eAPA_SubunitPlug; + + if ( getPlugAddressType() == eAPA_FunctionBlockPlug ) { + direction = getDirection(); + } else if ( getPlugAddressType() == eAPA_SubunitPlug ) { + direction = toggleDirection( getDirection() ); + } else { + // unit + direction = getDirection(); + } + + plugId = pSubunitPlugAddress->m_plugId; + debugOutput( DEBUG_LEVEL_VERBOSE, + "'(%d) %s': Remote plug is a subunit plug " + "(%d, %d, %s, %d)\n", + getGlobalId(), + getName(), + subunitType, + subunitId, + avPlugDirectionToString( direction ), + plugId ); + } + + if ( pFunctionBlockPlugAddress ) { + subunitType = pFunctionBlockPlugAddress->m_subunitType; + subunitId = pFunctionBlockPlugAddress->m_subunitId; + functionBlockType = pFunctionBlockPlugAddress->m_functionBlockType; + functionBlockId = pFunctionBlockPlugAddress->m_functionBlockId; + addressType = eAPA_FunctionBlockPlug; + + if ( getPlugAddressType() == eAPA_FunctionBlockPlug ) { + direction = toggleDirection( getDirection() ); + } else if ( getPlugAddressType() == eAPA_SubunitPlug ){ + direction = getDirection(); + } else { + debugError( "Function block has connection from/to unknown " + "plug type\n" ); + direction = eAPD_Unknown; + } + + plugId = pFunctionBlockPlugAddress->m_plugId; + + debugOutput( DEBUG_LEVEL_VERBOSE, + "'(%d) %s': Remote plug is a functionblock plug " + "(%d, %d, %d, %d, %s, %d)\n", + getGlobalId(), + getName(), + subunitType, + subunitId, + functionBlockType, + functionBlockId, + avPlugDirectionToString( direction ), + plugId ); + } + + ESubunitType enumSubunitType = + static_cast( subunitType ); + + return m_unit->getPlugManager().getPlug( + enumSubunitType, + subunitId, + functionBlockType, + functionBlockId, + addressType, + direction, + plugId ); +} + +Plug::EPlugDirection +Plug::toggleDirection( EPlugDirection direction ) const +{ + EPlugDirection newDirection; + switch ( direction ) { + case eAPD_Output: + newDirection = eAPD_Input; + break; + case eAPD_Input: + newDirection = eAPD_Output; + break; + default: + newDirection = direction; + } + + return newDirection; +} + +bool +Plug::serializeChannelInfos( Glib::ustring basePath, + Util::IOSerialize& ser, + const ClusterInfo& clusterInfo ) const +{ + bool result = true; + int i = 0; + for ( ChannelInfoVector::const_iterator it = clusterInfo.m_channelInfos.begin(); + it != clusterInfo.m_channelInfos.end(); + ++it ) + { + const ChannelInfo& info = *it; + std::ostringstream strstrm; + strstrm << basePath << i; + + result &= ser.write( strstrm.str() + "/m_streamPosition", info.m_streamPosition ); + result &= ser.write( strstrm.str() + "/m_location", info.m_location ); + result &= ser.write( strstrm.str() + "/m_name", info.m_name ); + } + + return result; +} + +bool +Plug::deserializeChannelInfos( Glib::ustring basePath, + Util::IODeserialize& deser, + ClusterInfo& clusterInfo ) +{ + int i = 0; + bool bFinished = false; + bool result = true; + do { + std::ostringstream strstrm; + strstrm << basePath << i; + + // check for one element to exist. when one exist the other elements + // must also be there. otherwise just return (last) result. + if ( deser.isExisting( strstrm.str() + "/m_streamPosition" ) ) { + ChannelInfo info; + + result &= deser.read( strstrm.str() + "/m_streamPosition", info.m_streamPosition ); + result &= deser.read( strstrm.str() + "/m_location", info.m_location ); + result &= deser.read( strstrm.str() + "/m_name", info.m_name ); + + if ( result ) { + clusterInfo.m_channelInfos.push_back( info ); + i++; + } else { + bFinished = true; + } + } else { + bFinished = true; + } + } while ( !bFinished ); + + return result; +} + + +bool +Plug::serializeClusterInfos( Glib::ustring basePath, + Util::IOSerialize& ser ) const +{ + bool result = true; + int i = 0; + for ( ClusterInfoVector::const_iterator it = m_clusterInfos.begin(); + it != m_clusterInfos.end(); + ++it ) + { + const ClusterInfo& info = *it; + std::ostringstream strstrm; + strstrm << basePath << i; + + result &= ser.write( strstrm.str() + "/m_index", info.m_index ); + result &= ser.write( strstrm.str() + "/m_portType", info.m_portType ); + result &= ser.write( strstrm.str() + "/m_name", info.m_name ); + result &= ser.write( strstrm.str() + "/m_nrOfChannels", info.m_nrOfChannels ); + result &= serializeChannelInfos( strstrm.str() + "/m_channelInfo", ser, info ); + result &= ser.write( strstrm.str() + "/m_streamFormat", info.m_streamFormat ); + + } + + return result; +} + +bool +Plug::deserializeClusterInfos( Glib::ustring basePath, + Util::IODeserialize& deser ) +{ + int i = 0; + bool bFinished = false; + bool result = true; + do { + std::ostringstream strstrm; + strstrm << basePath << i; + + // check for one element to exist. when one exist the other elements + // must also be there. otherwise just return (last) result. + if ( deser.isExisting( strstrm.str() + "/m_index" ) ) { + ClusterInfo info; + + result &= deser.read( strstrm.str() + "/m_index", info.m_index ); + result &= deser.read( strstrm.str() + "/m_portType", info.m_portType ); + result &= deser.read( strstrm.str() + "/m_name", info.m_name ); + result &= deser.read( strstrm.str() + "/m_nrOfChannels", info.m_nrOfChannels ); + result &= deserializeChannelInfos( strstrm.str() + "/m_channelInfo", deser, info ); + result &= deser.read( strstrm.str() + "/m_streamFormat", info.m_streamFormat ); + + if ( result ) { + m_clusterInfos.push_back( info ); + i++; + } else { + bFinished = true; + } + } else { + bFinished = true; + } + } while ( !bFinished ); + + return result; +} + + +bool +Plug::serializeFormatInfos( Glib::ustring basePath, + Util::IOSerialize& ser ) const +{ + bool result = true; + int i = 0; + for ( FormatInfoVector::const_iterator it = m_formatInfos.begin(); + it != m_formatInfos.end(); + ++it ) + { + const FormatInfo& info = *it; + std::ostringstream strstrm; + strstrm << basePath << i; + + result &= ser.write( strstrm.str() + "/m_samplingFrequency", info.m_samplingFrequency ); + result &= ser.write( strstrm.str() + "/m_isSyncStream", info.m_isSyncStream ); + result &= ser.write( strstrm.str() + "/m_audioChannels", info.m_audioChannels ); + result &= ser.write( strstrm.str() + "/m_midiChannels", info.m_midiChannels ); + result &= ser.write( strstrm.str() + "/m_index", info.m_index ); + } + return result; +} + +bool +Plug::deserializeFormatInfos( Glib::ustring basePath, + Util::IODeserialize& deser ) +{ + int i = 0; + bool bFinished = false; + bool result = true; + do { + std::ostringstream strstrm; + strstrm << basePath << i; + + // check for one element to exist. when one exist the other elements + // must also be there. otherwise just return (last) result. + if ( deser.isExisting( strstrm.str() + "/m_samplingFrequency" ) ) { + FormatInfo info; + + result &= deser.read( strstrm.str() + "/m_samplingFrequency", info.m_samplingFrequency ); + result &= deser.read( strstrm.str() + "/m_isSyncStream", info.m_isSyncStream ); + result &= deser.read( strstrm.str() + "/m_audioChannels", info.m_audioChannels ); + result &= deser.read( strstrm.str() + "/m_midiChannels", info.m_midiChannels ); + result &= deser.read( strstrm.str() + "/m_index", info.m_index ); + + if ( result ) { + m_formatInfos.push_back( info ); + i++; + } else { + bFinished = true; + } + } else { + bFinished = true; + } + } while ( !bFinished ); + + return result; +} + + +bool +Plug::serializePlugVector( Glib::ustring basePath, + Util::IOSerialize& ser, + const PlugVector& vec) const +{ + bool result = true; + int i = 0; + for ( PlugVector::const_iterator it = vec.begin(); + it != vec.end(); + ++it ) + { + const Plug* pPlug = *it; + std::ostringstream strstrm; + strstrm << basePath << i; + + result &= ser.write( strstrm.str() + "/global_id", pPlug->getGlobalId() ); + i++; + } + return result; +} + +bool +Plug::deserializePlugVector( Glib::ustring basePath, + Util::IODeserialize& deser, + PlugVector& vec ) +{ + int i = 0; + bool bFinished = false; + bool result = true; + do { + std::ostringstream strstrm; + strstrm << basePath << i; + + // check for one element to exist. when one exist the other elements + // must also be there. otherwise just return (last) result. + if ( deser.isExisting( strstrm.str() + "/global_id" ) ) { + unsigned int iPlugId; + result &= deser.read( strstrm.str() + "/global_id", iPlugId ); + + if ( result ) { + Plug* pPlug = m_unit->getPlugManager().getPlug( iPlugId ); + if ( pPlug ) { + vec.push_back( pPlug ); + } else { + result = false; + bFinished = true; + } + i++; + } else { + bFinished = true; + } + } else { + bFinished = true; + } + } while ( !bFinished ); + + return result; +} + +bool +Plug::serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const +{ + bool result=true; + result &= ser.write( basePath + "m_subunitType", getSubunitType()); + result &= ser.write( basePath + "m_subunitId", getSubunitId()); + result &= ser.write( basePath + "m_functionBlockType", m_functionBlockType); + result &= ser.write( basePath + "m_functionBlockId", m_functionBlockId); + result &= ser.write( basePath + "m_addressType", m_addressType ); + result &= ser.write( basePath + "m_direction", m_direction); + result &= ser.write( basePath + "m_id", m_id); + result &= ser.write( basePath + "m_infoPlugType", m_infoPlugType); + result &= ser.write( basePath + "m_nrOfChannels", m_nrOfChannels); + result &= ser.write( basePath + "m_name", m_name); + result &= serializeClusterInfos( basePath + "m_clusterInfos", ser ); + result &= ser.write( basePath + "m_samplingFrequency", m_samplingFrequency); + result &= serializeFormatInfos( basePath + "m_formatInfo", ser ); + result &= serializePlugVector( basePath + "m_inputConnections", ser, m_inputConnections ); + result &= serializePlugVector( basePath + "m_outputConnections", ser, m_outputConnections ); + result &= ser.write( basePath + "m_verbose_level", getDebugLevel()); + result &= ser.write( basePath + "m_globalId", m_globalId); + result &= ser.write( basePath + "m_globalIdCounter", m_globalIdCounter ); + + return result; +} + +Plug* +Plug::deserialize( Glib::ustring basePath, + Util::IODeserialize& deser, + Unit& unit, + PlugManager& plugManager ) +{ + #warning FIXME: The derived class should be creating these + // FIXME: The derived class should be creating these, such that discover() can become pure virtual + + if ( !deser.isExisting( basePath + "m_subunitType" ) ) { + return 0; + } + Plug* pPlug = new Plug; + if ( !pPlug ) { + return 0; + } + + pPlug->m_unit = &unit; + + bool result=true; + + ESubunitType subunitType; + result = deser.read( basePath + "m_subunitType", subunitType ); + subunit_t subunitId; + result &= deser.read( basePath + "m_subunitId", subunitId ); + pPlug->m_subunit = unit.getSubunit( subunitType, subunitType ); + + result &= deser.read( basePath + "m_functionBlockType", pPlug->m_functionBlockType ); + result &= deser.read( basePath + "m_functionBlockId", pPlug->m_functionBlockId ); + result &= deser.read( basePath + "m_addressType", pPlug->m_addressType ); + result &= deser.read( basePath + "m_direction", pPlug->m_direction ); + result &= deser.read( basePath + "m_id", pPlug->m_id ); + result &= deser.read( basePath + "m_infoPlugType", pPlug->m_infoPlugType ); + result &= deser.read( basePath + "m_nrOfChannels", pPlug->m_nrOfChannels ); + result &= deser.read( basePath + "m_name", pPlug->m_name ); + result &= pPlug->deserializeClusterInfos( basePath + "m_clusterInfos", deser ); + result &= deser.read( basePath + "m_samplingFrequency", pPlug->m_samplingFrequency ); + result &= pPlug->deserializeFormatInfos( basePath + "m_formatInfos", deser ); + // input and output connections can't be processed here because not all plugs might + // deserialized at this point. so we do that in deserializeUpdate. + int level; + result &= deser.read( basePath + "m_verbose_level", level ); + setDebugLevel(level); + result &= deser.read( basePath + "m_globalId", pPlug->m_globalId ); + result &= deser.read( basePath + "m_globalIdCounter", pPlug->m_globalIdCounter ); + + if ( !result ) { + delete pPlug; + return 0; + } + + return pPlug; +} + +bool +Plug::deserializeUpdate( Glib::ustring basePath, + Util::IODeserialize& deser ) +{ + bool result; + + result = deserializePlugVector( basePath + "m_inputConnections", deser, m_inputConnections ); + result &= deserializePlugVector( basePath + "m_outputConnections", deser, m_outputConnections ); + + return result; +} + +///////////////////////////////////////// +///////////////////////////////////////// + +const char* avPlugAddressTypeStrings[] = +{ + "PCR", + "external", + "asynchronous", + "subunit", + "functionblock", + "undefined", +}; + +const char* avPlugAddressTypeToString( Plug::EPlugAddressType type ) +{ + if ( type > ( int )( sizeof( avPlugAddressTypeStrings ) + / sizeof( avPlugAddressTypeStrings[0] ) ) ) + { + type = Plug::eAPA_Undefined; + } + return avPlugAddressTypeStrings[type]; +} + +const char* avPlugTypeStrings[] = +{ + "IsoStream", + "AsyncStream", + "MIDI", + "Sync", + "Analog", + "Digital", + "Unknown", +}; + +const char* avPlugTypeToString( Plug::EPlugType type ) +{ + if ( type > ( int )( sizeof( avPlugTypeStrings ) + / sizeof( avPlugTypeStrings[0] ) ) ) + { + type = Plug::eAPT_Unknown; + } + return avPlugTypeStrings[type]; +} + +const char* avPlugDirectionStrings[] = +{ + "Input", + "Output", + "Unknown", +}; + +const char* avPlugDirectionToString( Plug::EPlugDirection type ) +{ + if ( type > ( int )( sizeof( avPlugDirectionStrings ) + / sizeof( avPlugDirectionStrings[0] ) ) ) + { + type = Plug::eAPD_Unknown; + } + return avPlugDirectionStrings[type]; +} + +///////////////////////////////////// + + +PlugManager::PlugManager( ) +{ + +} + +PlugManager::PlugManager( const PlugManager& rhs ) +{ + setDebugLevel( rhs.getDebugLevel() ); +} + +PlugManager::~PlugManager() +{ +} + +bool +PlugManager::addPlug( Plug& plug ) +{ + m_plugs.push_back( &plug ); + return true; +} + +bool +PlugManager::remPlug( Plug& plug ) +{ + for ( PlugVector::iterator it = m_plugs.begin(); + it != m_plugs.end(); + ++it ) + { + Plug* plugIt = *it; + if ( plugIt == &plug ) { + m_plugs.erase( it ); + return true; + } + } + return false; +} + +// helper function +static void addConnection( PlugConnectionVector& connections, + Plug& srcPlug, + Plug& destPlug ) +{ + for ( PlugConnectionVector::iterator it = connections.begin(); + it != connections.end(); + ++it ) + { + PlugConnection* con = *it; + if ( ( &( con->getSrcPlug() ) == &srcPlug ) + && ( &( con->getDestPlug() ) == &destPlug ) ) + { + return; + } + } + connections.push_back( new PlugConnection( srcPlug, destPlug ) ); +} + +bool +PlugManager::tidyPlugConnections(PlugConnectionVector& connections) +{ + for ( PlugVector::const_iterator it = m_plugs.begin(); + it != m_plugs.end(); + ++it ) + { + Plug* plug = *it; + for ( PlugVector::const_iterator it = + plug->getInputConnections().begin(); + it != plug->getInputConnections().end(); + ++it ) + { + addConnection( connections, *( *it ), *plug ); + } + plug->getInputConnections().clear(); + + for ( PlugVector::const_iterator it = + plug->getOutputConnections().begin(); + it != plug->getOutputConnections().end(); + ++it ) + { + addConnection( connections, *plug, *( *it ) ); + } + plug->getOutputConnections().clear(); + } + + for ( PlugConnectionVector::iterator it = connections.begin(); + it != connections.end(); + ++it ) + { + PlugConnection * con = *it; + con->getSrcPlug().getOutputConnections().push_back(&( con->getDestPlug() )); + con->getDestPlug().getInputConnections().push_back(&( con->getSrcPlug() )); + + } + + return true; +} + +static void addConnectionOwner( PlugConnectionOwnerVector& connections, + Plug& srcPlug, + Plug& destPlug ) +{ + + for ( PlugConnectionOwnerVector::iterator it = connections.begin(); + it != connections.end(); + ++it ) + { + PlugConnection& con = *it; + if ( ( &( con.getSrcPlug() ) == &srcPlug ) + && ( &( con.getDestPlug() ) == &destPlug ) ) + { + return; + } + } + connections.push_back( PlugConnection( srcPlug, destPlug ) ); +} + + +void +PlugManager::showPlugs() const +{ + // \todo The information provided here could be better arranged. For a start it is ok, but + // there is room for improvement. Something for a lazy sunday afternoon (tip: maybe drink some + // beer to get into the mood) + + printf( "\nSummary\n" ); + printf( "-------\n\n" ); + printf( "Nr | AddressType | Direction | SubUnitType | SubUnitId | FunctionBlockType | FunctionBlockId | Id | Type |Name\n" ); + printf( "---+-----------------+-----------+-------------+-----------+-------------------+-----------------+------+--------------+------\n" ); + + for ( PlugVector::const_iterator it = m_plugs.begin(); + it != m_plugs.end(); + ++it ) + { + Plug* plug = *it; + + printf( "%2d | %15s | %9s | %11s | 0x%02x | 0x%02x | 0x%02x | 0x%02x | %12s | %s\n", + plug->getGlobalId(), + avPlugAddressTypeToString( plug->getPlugAddressType() ), + avPlugDirectionToString( plug->getDirection() ), + subunitTypeToString( plug->getSubunitType() ), + plug->getSubunitId(), + plug->getFunctionBlockType(), + plug->getFunctionBlockId(), + plug->getPlugId(), + avPlugTypeToString( plug->getPlugType() ), + plug->getName() ); + } + + printf( "\nConnections\n" ); + printf( "-----------\n" ); + + PlugConnectionOwnerVector connections; + + for ( PlugVector::const_iterator it = m_plugs.begin(); + it != m_plugs.end(); + ++it ) + { + Plug* plug = *it; + for ( PlugVector::const_iterator it = + plug->getInputConnections().begin(); + it != plug->getInputConnections().end(); + ++it ) + { + addConnectionOwner( connections, *( *it ), *plug ); + } + for ( PlugVector::const_iterator it = + plug->getOutputConnections().begin(); + it != plug->getOutputConnections().end(); + ++it ) + { + addConnectionOwner( connections, *plug, *( *it ) ); + } + } + + printf( "digraph avcconnections {\n" ); + for ( PlugConnectionOwnerVector::iterator it = connections.begin(); + it != connections.end(); + ++it ) + { + PlugConnection& con = *it; + printf( "\t\"(%d) %s\" -> \"(%d) %s\"\n", + con.getSrcPlug().getGlobalId(), + con.getSrcPlug().getName(), + con.getDestPlug().getGlobalId(), + con.getDestPlug().getName() ); + } + for ( PlugVector::const_iterator it = m_plugs.begin(); + it != m_plugs.end(); + ++it ) + { + Plug* plug = *it; + if ( plug->getFunctionBlockType() != 0xff ) { + std::ostringstream strstrm; + switch(plug->getFunctionBlockType()) { + case 0x80: + strstrm << "Selector FB"; + break; + case 0x81: + strstrm << "Feature FB"; + break; + case 0x82: + strstrm << "Processing FB"; + break; + case 0x83: + strstrm << "CODEC FB"; + break; + default: + strstrm << plug->getFunctionBlockType(); + } + + if ( plug->getPlugDirection() == Plug::eAPD_Input ) { + printf( "\t\"(%d) %s\" -> \"(%s, ID %d)\"\n", + plug->getGlobalId(), + plug->getName(), + strstrm.str().c_str(), + plug->getFunctionBlockId() ); + } else { + printf( "\t\"(%s, ID %d)\" -> \t\"(%d) %s\"\n", + strstrm.str().c_str(), + plug->getFunctionBlockId(), + plug->getGlobalId(), + plug->getName() ); + } + } + } + + const char* colorStrings[] = { + "coral", + "slateblue", + "white", + "green", + "yellow", + "grey", + }; + + for ( PlugVector::const_iterator it = m_plugs.begin(); + it != m_plugs.end(); + ++it ) + { + Plug* plug = *it; + printf( "\t\"(%d) %s\" [color=%s,style=filled];\n", + plug->getGlobalId(), plug->getName(), + colorStrings[plug->getPlugAddressType() ] ); + } + + printf("}\n" ); + printf( "Use \"dot -Tps FILENAME.dot -o FILENAME.ps\" " + "to generate graph\n"); + + debugOutput( DEBUG_LEVEL_VERBOSE, "Plug details\n" ); + debugOutput( DEBUG_LEVEL_VERBOSE, "------------\n" ); + for ( PlugVector::const_iterator it = m_plugs.begin(); + it != m_plugs.end(); + ++it ) + { + Plug* plug = *it; + debugOutput( DEBUG_LEVEL_VERBOSE, "Plug %d:\n", plug->getGlobalId() ); + plug->showPlug(); + + } +} + +Plug* +PlugManager::getPlug( ESubunitType subunitType, + subunit_id_t subunitId, + function_block_type_t functionBlockType, + function_block_id_t functionBlockId, + Plug::EPlugAddressType plugAddressType, + Plug::EPlugDirection plugDirection, + plug_id_t plugId ) const +{ + debugOutput( DEBUG_LEVEL_VERBOSE, "SBT, SBID, FBT, FBID, AT, PD, ID = " + "(0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x)\n", + subunitType, + subunitId, + functionBlockType, + functionBlockId, + plugAddressType, + plugDirection, + plugId ); + + for ( PlugVector::const_iterator it = m_plugs.begin(); + it != m_plugs.end(); + ++it ) + { + Plug* plug = *it; + + if ( ( subunitType == plug->getSubunitType() ) + && ( subunitId == plug->getSubunitId() ) + && ( functionBlockType == plug->getFunctionBlockType() ) + && ( functionBlockId == plug->getFunctionBlockId() ) + && ( plugAddressType == plug->getPlugAddressType() ) + && ( plugDirection == plug->getPlugDirection() ) + && ( plugId == plug->getPlugId() ) ) + { + return plug; + } + } + + return 0; +} + +Plug* +PlugManager::getPlug( int iGlobalId ) const +{ + for ( PlugVector::const_iterator it = m_plugs.begin(); + it != m_plugs.end(); + ++it ) + { + Plug* pPlug = *it; + if ( pPlug->getGlobalId() == iGlobalId ) { + return pPlug; + } + } + + return 0; +} + +PlugVector +PlugManager::getPlugsByType( ESubunitType subunitType, + subunit_id_t subunitId, + function_block_type_t functionBlockType, + function_block_id_t functionBlockId, + Plug::EPlugAddressType plugAddressType, + Plug::EPlugDirection plugDirection, + Plug::EPlugType type) const +{ + debugOutput( DEBUG_LEVEL_VERBOSE, "SBT, SBID, FBT, FBID, AT, PD, T = " + "(0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x)\n", + subunitType, + subunitId, + functionBlockType, + functionBlockId, + plugAddressType, + plugDirection, + type ); + + PlugVector plugVector; + for ( PlugVector::const_iterator it = m_plugs.begin(); + it != m_plugs.end(); + ++it ) + { + Plug* pPlug = *it; + + if ( ( subunitType == pPlug->getSubunitType() ) + && ( subunitId == pPlug->getSubunitId() ) + && ( functionBlockType == pPlug->getFunctionBlockType() ) + && ( functionBlockId == pPlug->getFunctionBlockId() ) + && ( plugAddressType == pPlug->getPlugAddressType() ) + && ( plugDirection == pPlug->getPlugDirection() ) + && ( type == pPlug->getPlugType() ) ) + { + plugVector.push_back( pPlug ); + } + } + + return plugVector; +} + +bool +PlugManager::serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const +{ + bool result = true; + int i = 0; + for ( PlugVector::const_iterator it = m_plugs.begin(); + it != m_plugs.end(); + ++it ) + { + Plug* pPlug = *it; + std::ostringstream strstrm; + strstrm << basePath << i; + result &= pPlug->serialize( strstrm.str() + "/", ser ); + i++; + } + + return result; +} + +PlugManager* +PlugManager::deserialize( Glib::ustring basePath, + Util::IODeserialize& deser, + Unit& unit ) + +{ + PlugManager* pMgr = new PlugManager; + + if ( !pMgr ) { + return 0; + } + + int i = 0; + bool bFinished = false; + do { + std::ostringstream strstrm; + strstrm << basePath << i; + // unit still holds a null pointer for the plug manager + // therefore we have to *this as additional argument + Plug* pPlug = Plug::deserialize( strstrm.str() + "/", + deser, + unit, + *pMgr ); + if ( pPlug ) { + pMgr->m_plugs.push_back( pPlug ); + i++; + } else { + bFinished = true; + } + } while ( !bFinished ); + + return pMgr; +} + + +//////////////////////////////////// + +PlugConnection::PlugConnection( Plug& srcPlug, Plug& destPlug ) + : m_srcPlug( &srcPlug ) + , m_destPlug( &destPlug ) +{ +} + +PlugConnection::PlugConnection() + : m_srcPlug( 0 ) + , m_destPlug( 0 ) +{ +} + +bool +PlugConnection::serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const +{ + bool result; + result = ser.write( basePath + "m_srcPlug", m_srcPlug->getGlobalId() ); + result &= ser.write( basePath + "m_destPlug", m_destPlug->getGlobalId() ); + return result; +} + +PlugConnection* +PlugConnection::deserialize( Glib::ustring basePath, + Util::IODeserialize& deser, + Unit& unit ) +{ + if ( !deser.isExisting( basePath + "m_srcPlug" ) ) { + return 0; + } + PlugConnection* pConnection = new PlugConnection; + if ( !pConnection ) { + return 0; + } + + bool result; + int iSrcPlugId; + int iDestPlugId; + result = deser.read( basePath + "m_srcPlug", iSrcPlugId ); + result &= deser.read( basePath + "m_destPlug", iDestPlugId ); + + if ( !result ) { + delete pConnection; + return 0; + } + + pConnection->m_srcPlug = unit.getPlugManager().getPlug( iSrcPlugId ); + pConnection->m_destPlug = unit.getPlugManager().getPlug( iDestPlugId ); + + if ( !pConnection->m_srcPlug || !pConnection->m_destPlug ) { + delete pConnection; + return 0; + } + + return pConnection; +} + +ExtendedStreamFormatCmd +Plug::setPlugAddrToStreamFormatCmd( + ExtendedStreamFormatCmd::ESubFunction subFunction) +{ + ExtendedStreamFormatCmd extStreamFormatInfoCmd( + m_unit->get1394Service(), + subFunction ); + switch( getSubunitType() ) { + case eST_Unit: + { + UnitPlugAddress::EPlugType ePlugType = + UnitPlugAddress::ePT_Unknown; + switch ( m_addressType ) { + case eAPA_PCR: + ePlugType = UnitPlugAddress::ePT_PCR; + break; + case eAPA_ExternalPlug: + ePlugType = UnitPlugAddress::ePT_ExternalPlug; + break; + case eAPA_AsynchronousPlug: + ePlugType = UnitPlugAddress::ePT_AsynchronousPlug; + break; + default: + ePlugType = UnitPlugAddress::ePT_Unknown; + } + UnitPlugAddress unitPlugAddress( ePlugType, + m_id ); + extStreamFormatInfoCmd.setPlugAddress( + PlugAddress( convertPlugDirection( getPlugDirection() ), + PlugAddress::ePAM_Unit, + unitPlugAddress ) ); + } + break; + case eST_Music: + case eST_Audio: + { + switch( m_addressType ) { + case eAPA_SubunitPlug: + { + SubunitPlugAddress subunitPlugAddress( m_id ); + extStreamFormatInfoCmd.setPlugAddress( + PlugAddress( convertPlugDirection( getPlugDirection() ), + PlugAddress::ePAM_Subunit, + subunitPlugAddress ) ); + } + break; + case eAPA_FunctionBlockPlug: + { + FunctionBlockPlugAddress functionBlockPlugAddress( + m_functionBlockType, + m_functionBlockId, + m_id ); + extStreamFormatInfoCmd.setPlugAddress( + PlugAddress( convertPlugDirection( getPlugDirection() ), + PlugAddress::ePAM_FunctionBlock, + functionBlockPlugAddress ) ); + } + break; + default: + extStreamFormatInfoCmd.setPlugAddress(PlugAddress()); + } + } + break; + default: + debugError( "Unknown subunit type\n" ); + } + + extStreamFormatInfoCmd.setNodeId( m_unit->getConfigRom().getNodeId() ); + extStreamFormatInfoCmd.setCommandType( AVCCommand::eCT_Status ); + extStreamFormatInfoCmd.setSubunitId( getSubunitId() ); + extStreamFormatInfoCmd.setSubunitType( getSubunitType() ); + + return extStreamFormatInfoCmd; +} + +} Index: trunk/libffado/src/libavc/general/avc_extended_plug_info.h =================================================================== --- trunk/libffado/src/libavc/general/avc_extended_plug_info.h (revision 503) +++ trunk/libffado/src/libavc/general/avc_extended_plug_info.h (revision 503) @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVCEXTENDEDPLUGINFO_H +#define AVCEXTENDEDPLUGINFO_H + +#include "avc_extended_cmd_generic.h" +#include "avc_generic.h" + +#include + +#include +#include + +namespace AVC { + +class ExtendedPlugInfoPlugTypeSpecificData : public IBusData +{ +public: + enum EExtendedPlugInfoPlugType { + eEPIPT_IsoStream = 0x0, + eEPIPT_AsyncStream = 0x1, + eEPIPT_Midi = 0x2, + eEPIPT_Sync = 0x3, + eEPIPT_Analog = 0x4, + eEPIPT_Digital = 0x5, + + eEPIPT_Unknown = 0xff, + }; + + ExtendedPlugInfoPlugTypeSpecificData( EExtendedPlugInfoPlugType ePlugType = eEPIPT_Unknown); + virtual ~ExtendedPlugInfoPlugTypeSpecificData(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual ExtendedPlugInfoPlugTypeSpecificData* clone() const; + + typedef byte_t plug_type_t; + + plug_type_t m_plugType; +}; + +const char* extendedPlugInfoPlugTypeToString( plug_type_t plugType ); + +///////////////////////////////////////// + +class ExtendedPlugInfoPlugNameSpecificData : public IBusData +{ +public: + ExtendedPlugInfoPlugNameSpecificData(); + virtual ~ExtendedPlugInfoPlugNameSpecificData(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual ExtendedPlugInfoPlugNameSpecificData* clone() const; + + std::string m_name; +}; + +///////////////////////////////////////// + +class ExtendedPlugInfoPlugNumberOfChannelsSpecificData : public IBusData +{ +public: + ExtendedPlugInfoPlugNumberOfChannelsSpecificData(); + virtual ~ExtendedPlugInfoPlugNumberOfChannelsSpecificData(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual ExtendedPlugInfoPlugNumberOfChannelsSpecificData* clone() const; + + nr_of_channels_t m_nrOfChannels; +}; + + +///////////////////////////////////////// + +class ExtendedPlugInfoPlugChannelPositionSpecificData : public IBusData +{ +public: + enum ELocation { + eEPI_LeftFront = 0x01, + eEPI_RightFront = 0x02, + eEPI_Center = 0x03, + eEPI_Subwoofer = 0x04, + eEPI_LeftSurround = 0x05, + eEPI_RightSurround = 0x06, + eEPI_LeftOfCenter = 0x07, + eEPI_RightOfCenter = 0x08, + eEPI_Surround = 0x09, + eEPI_SideLeft = 0x0a, + eEPI_SideRight = 0x0b, + eEPI_Top = 0x0c, + eEPI_Bottom = 0x0d, + eEPI_LeftFrontEffect = 0x0e, + eEPI_RightFrontEffect = 0x0f, + eEPI_NoPostion = 0xff, + }; + + struct ChannelInfo { + stream_position_t m_streamPosition; + stream_position_location_t m_location; + }; + + typedef std::vector ChannelInfoVector; + + struct ClusterInfo { + nr_of_channels_t m_nrOfChannels; + ChannelInfoVector m_channelInfos; + }; + + ExtendedPlugInfoPlugChannelPositionSpecificData(); + virtual ~ExtendedPlugInfoPlugChannelPositionSpecificData(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual ExtendedPlugInfoPlugChannelPositionSpecificData* clone() const; + + typedef std::vector ClusterInfoVector; + + nr_of_clusters_t m_nrOfClusters; + ClusterInfoVector m_clusterInfos; +}; + +///////////////////////////////////////// + +class ExtendedPlugInfoPlugChannelNameSpecificData : public IBusData +{ +public: + ExtendedPlugInfoPlugChannelNameSpecificData(); + virtual ~ExtendedPlugInfoPlugChannelNameSpecificData(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual ExtendedPlugInfoPlugChannelNameSpecificData* clone() const; + + stream_position_t m_streamPosition; + string_length_t m_stringLength; + std::string m_plugChannelName; +}; + +///////////////////////////////////////// + +class ExtendedPlugInfoPlugInputSpecificData : public IBusData +{ +public: + ExtendedPlugInfoPlugInputSpecificData(); + ExtendedPlugInfoPlugInputSpecificData( const ExtendedPlugInfoPlugInputSpecificData& rhs ); + virtual ~ExtendedPlugInfoPlugInputSpecificData(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual ExtendedPlugInfoPlugInputSpecificData* clone() const; + + PlugAddressSpecificData* m_plugAddress; +}; + + +///////////////////////////////////////// + +class ExtendedPlugInfoPlugOutputSpecificData : public IBusData +{ +public: + ExtendedPlugInfoPlugOutputSpecificData(); + ExtendedPlugInfoPlugOutputSpecificData( const ExtendedPlugInfoPlugOutputSpecificData& rhs ); + virtual ~ExtendedPlugInfoPlugOutputSpecificData(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual ExtendedPlugInfoPlugOutputSpecificData* clone() const; + + number_of_output_plugs_t m_nrOfOutputPlugs; + + typedef std::vector PlugAddressVector; + PlugAddressVector m_outputPlugAddresses; +}; + +///////////////////////////////////////// + +class ExtendedPlugInfoClusterInfoSpecificData : public IBusData +{ +public: + enum EPortType { + ePT_Speaker = 0x00, + ePT_Headphone = 0x01, + ePT_Microphone = 0x02, + ePT_Line = 0x03, + ePT_SPDIF = 0x04, + ePT_ADAT = 0x05, + ePT_TDIF = 0x06, + ePT_MADI = 0x07, + ePT_Analog = 0x08, + ePT_Digital = 0x09, + ePT_MIDI = 0x0a, + ePT_NoType = 0xff, + }; + + ExtendedPlugInfoClusterInfoSpecificData(); + virtual ~ExtendedPlugInfoClusterInfoSpecificData(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual ExtendedPlugInfoClusterInfoSpecificData* clone() const; + + cluster_index_t m_clusterIndex; + port_type_t m_portType; + string_length_t m_stringLength; + std::string m_clusterName; +}; + +const char* extendedPlugInfoClusterInfoPortTypeToString( port_type_t portType ); + +///////////////////////////////////////// + +#define AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_TYPE 0x00 +#define AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_NAME 0x01 +#define AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_NO_OF_CHANNELS 0x02 +#define AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_CHANNEL_POSITION 0x03 +#define AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_CHANNEL_NAME 0x04 +#define AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_INPUT 0x05 +#define AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_OUTPUT 0x06 +#define AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_CLUSTER_INFO 0x07 + +class ExtendedPlugInfoInfoType : public IBusData +{ +public: + enum EInfoType { + eIT_PlugType = AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_TYPE, + eIT_PlugName = AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_NAME, + eIT_NoOfChannels = AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_NO_OF_CHANNELS, + eIT_ChannelPosition = AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_CHANNEL_POSITION, + eIT_ChannelName = AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_CHANNEL_NAME, + eIT_PlugInput = AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_INPUT, + eIT_PlugOutput = AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_OUTPUT, + eIT_ClusterInfo = AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_CLUSTER_INFO, + }; + + ExtendedPlugInfoInfoType(EInfoType eInfoType); + ExtendedPlugInfoInfoType( const ExtendedPlugInfoInfoType& rhs ); + virtual ~ExtendedPlugInfoInfoType(); + + bool initialize(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual ExtendedPlugInfoInfoType* clone() const; + + info_type_t m_infoType; + + ExtendedPlugInfoPlugTypeSpecificData* m_plugType; + ExtendedPlugInfoPlugNameSpecificData* m_plugName; + ExtendedPlugInfoPlugNumberOfChannelsSpecificData* m_plugNrOfChns; + ExtendedPlugInfoPlugChannelPositionSpecificData* m_plugChannelPosition; + ExtendedPlugInfoPlugChannelNameSpecificData* m_plugChannelName; + ExtendedPlugInfoPlugInputSpecificData* m_plugInput; + ExtendedPlugInfoPlugOutputSpecificData* m_plugOutput; + ExtendedPlugInfoClusterInfoSpecificData* m_plugClusterInfo; +}; + +const char* extendedPlugInfoInfoTypeToString( info_type_t infoType ); + +///////////////////////////////////////////////////////// + +#define AVC1394_PLUG_INFO_SUBFUNCTION_EXTENDED_PLUG_INFO_CMD 0xC0 +#define AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_NOT_USED 0xFF + + +class ExtendedPlugInfoCmd: public AVCCommand +{ +public: + enum ESubFunction { + eSF_ExtendedPlugInfoCmd = AVC1394_PLUG_INFO_SUBFUNCTION_EXTENDED_PLUG_INFO_CMD, + eSF_NotUsed = AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_NOT_USED, + }; + + ExtendedPlugInfoCmd( Ieee1394Service& ieee1394service, + ESubFunction eSubFunction = eSF_ExtendedPlugInfoCmd ); + ExtendedPlugInfoCmd( const ExtendedPlugInfoCmd& rhs ); + virtual ~ExtendedPlugInfoCmd(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + bool setPlugAddress( const PlugAddress& plugAddress ); + bool setSubFunction( ESubFunction subFunction ); + subfunction_t getSubFunction( ) {return m_subFunction;}; + bool setInfoType( const ExtendedPlugInfoInfoType& infoType ); + ExtendedPlugInfoInfoType* getInfoType() + { return m_infoType; } + + virtual const char* getCmdName() const + { return "ExtendedPlugInfoCmd"; } + +protected: + subfunction_t m_subFunction; + PlugAddress* m_plugAddress; + ExtendedPlugInfoInfoType* m_infoType; +}; + +} + +#endif Index: trunk/libffado/src/libavc/general/avc_subunit_info.h =================================================================== --- trunk/libffado/src/libavc/general/avc_subunit_info.h (revision 503) +++ trunk/libffado/src/libavc/general/avc_subunit_info.h (revision 503) @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVCSUBUNITINFO_H +#define AVCSUBUNITINFO_H + +#include "avc_generic.h" + +#include + + +namespace AVC { + +// No extended subunit queries supported + +class SubUnitInfoCmd: public AVCCommand +{ +public: + SubUnitInfoCmd( Ieee1394Service& ieee1349service ); + virtual ~SubUnitInfoCmd(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual const char* getCmdName() const + { return "SubUnitInfoCmd"; } + + bool clear(); + + page_t m_page; + extension_code_t m_extension_code; + + + + enum { + eMaxSubunitsPerPage = 4, + eMaxSubunitsPerUnit = 32, + }; + + struct TableEntry { + subunit_type_t m_subunit_type; + max_subunit_id_t m_max_subunit_id; + }; + + struct TableEntry m_table[eMaxSubunitsPerPage]; + + short getMaxNoOfPages() + { return eMaxSubunitsPerUnit / eMaxSubunitsPerPage; } + + + short m_nrOfValidEntries; + short getNrOfValidEntries() + { return m_nrOfValidEntries; } + +}; + +} + +#endif // AVCSUBUNITINFO_H Index: trunk/libffado/src/libavc/general/avc_plug.h =================================================================== --- trunk/libffado/src/libavc/general/avc_plug.h (revision 548) +++ trunk/libffado/src/libavc/general/avc_plug.h (revision 548) @@ -0,0 +1,383 @@ +/* + * Copyright (C) 2007 by Pieter Palmers + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVC_PLUG +#define AVC_PLUG + +#include "../ccm/avc_signal_source.h" +#include "../streamformat/avc_extended_stream_format.h" +#include "../avc_definitions.h" +#include "avc_generic.h" + +#include "libutil/serialize.h" + +#include "debugmodule/debugmodule.h" + +#include + +class Ieee1394Service; +class ConfigRom; + +namespace AVC { + +class Unit; +class Subunit; +class PlugManager; + +class Plug; +typedef std::vector PlugVector; + +class PlugConnection; +typedef std::vector PlugConnectionVector; + + +class Plug { +public: + + enum EPlugAddressType { + eAPA_PCR, + eAPA_ExternalPlug, + eAPA_AsynchronousPlug, + eAPA_SubunitPlug, + eAPA_FunctionBlockPlug, + eAPA_Undefined, + }; + std::string plugAddressTypeToString(enum EPlugAddressType t); + + enum EPlugType { + eAPT_IsoStream, + eAPT_AsyncStream, + eAPT_Midi, + eAPT_Sync, + eAPT_Analog, + eAPT_Digital, + eAPT_Unknown, + }; + std::string plugTypeToString(enum EPlugType t); + + enum EPlugDirection { + eAPD_Input, + eAPD_Output, + eAPD_Unknown, + }; + std::string plugDirectionToString(enum EPlugDirection t); + + // \todo This constructors sucks. too many parameters. fix it. + Plug( Unit* unit, + Subunit* subunit, + function_block_type_t functionBlockType, + function_block_type_t functionBlockId, + EPlugAddressType plugAddressType, + EPlugDirection plugDirection, + plug_id_t plugId ); + Plug( const Plug& rhs ); + virtual ~Plug(); + + bool inquireConnnection( Plug& plug ); + bool setConnection( Plug& plug ); + + int getSignalSource(); + + int getGlobalId() const + { return m_globalId; } + plug_id_t getPlugId() const + { return m_id; } + ESubunitType getSubunitType() const; + subunit_id_t getSubunitId() const; + + const char* getName() const + { return m_name.c_str(); } + bool setName(const char *n) + { m_name=n; return true;}; + bool setName(std::string n) + { m_name=n; return true;}; + EPlugDirection getPlugDirection() const + { return m_direction; } + bool setPlugDirection(EPlugDirection d) + { m_direction=d; return true; } + sampling_frequency_t getSamplingFrequency() const + { return m_samplingFrequency; } + int getSampleRate() const; // 22050, 24000, 32000, ... + bool setSampleRate( int rate ); + + int getNrOfChannels() const; + bool setNrOfChannels(int i); + int getNrOfStreams() const; + + // FIXME: this is the same as getPlugDirection + EPlugDirection getDirection() const + { return m_direction; } + EPlugAddressType getPlugAddressType() const + { return m_addressType; } + EPlugType getPlugType() const + { return m_infoPlugType; } + bool setPlugType(EPlugType t) + { m_infoPlugType=t; return true; } + + function_block_type_t getFunctionBlockType() const + { return m_functionBlockType; } + function_block_id_t getFunctionBlockId() const + { return m_functionBlockId; } + +// const PlugVector& getInputConnections() const +// { return m_inputConnections; } +// const PlugVector& getOutputConnections() const +// { return m_outputConnections; } + PlugVector& getInputConnections() + { return m_inputConnections; } + PlugVector& getOutputConnections() + { return m_outputConnections; } + + static PlugAddress::EPlugDirection convertPlugDirection( + EPlugDirection direction); + + void showPlug() const; + + bool serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const; + static Plug* deserialize( Glib::ustring basePath, + Util::IODeserialize& deser, + Unit& avDevice, + PlugManager& plugManager ); + + bool deserializeUpdate( Glib::ustring basePath, + Util::IODeserialize& deser ); + + public: + struct ChannelInfo { + stream_position_t m_streamPosition; + stream_position_location_t m_location; + Glib::ustring m_name; + }; + typedef std::vector ChannelInfoVector; + + struct ClusterInfo { + int m_index; + port_type_t m_portType; + Glib::ustring m_name; + + nr_of_channels_t m_nrOfChannels; + ChannelInfoVector m_channelInfos; + stream_format_t m_streamFormat; + }; + typedef std::vector ClusterInfoVector; + + ClusterInfoVector& getClusterInfos() + { return m_clusterInfos; } + + virtual void setVerboseLevel( int i ) + {setDebugLevel(i);}; + +// the discovery interface +// everything can be overloaded, or +// can be left as is +public: + virtual bool discover(); + virtual bool discoverConnections(); + virtual bool propagateFromConnectedPlug( ); + +protected: + virtual bool discoverPlugType(); + virtual bool discoverName(); + virtual bool discoverNoOfChannels(); + virtual bool discoverChannelPosition(); + virtual bool discoverChannelName(); + virtual bool discoverClusterInfo(); + virtual bool discoverStreamFormat(); + virtual bool discoverSupportedStreamFormats(); + virtual bool discoverConnectionsInput(); + virtual bool discoverConnectionsOutput(); + virtual bool initFromDescriptor(); + + bool propagateFromPlug( Plug *p ); + + ExtendedStreamFormatCmd setPlugAddrToStreamFormatCmd( + ExtendedStreamFormatCmd::ESubFunction subFunction); + +protected: + Plug(); + + SignalSourceCmd setSrcPlugAddrToSignalCmd(); + + void setDestPlugAddrToSignalCmd( + SignalSourceCmd& signalSourceCmd, Plug& plug ); + + void debugOutputClusterInfos( int debugLevel ); + + bool addPlugConnection( PlugVector& connections, Plug& plug ); + + bool discoverConnectionsFromSpecificData( + EPlugDirection discoverDirection, + PlugAddressSpecificData* plugAddress, + PlugVector& connections ); + + Plug* getPlugDefinedBySpecificData( + UnitPlugSpecificDataPlugAddress* pUnitPlugAddress, + SubunitPlugSpecificDataPlugAddress* pSubunitPlugAddress, + FunctionBlockPlugSpecificDataPlugAddress* pFunctionBlockPlugAddress ); + + EPlugDirection toggleDirection( EPlugDirection direction ) const; + + const ClusterInfo* getClusterInfoByIndex( int index ) const; + + bool serializeChannelInfos( Glib::ustring basePath, + Util::IOSerialize& ser, + const ClusterInfo& clusterInfo ) const; + bool deserializeChannelInfos( Glib::ustring basePath, + Util::IODeserialize& deser, + ClusterInfo& clusterInfo ); + + bool serializeClusterInfos( Glib::ustring basePath, + Util::IOSerialize& ser ) const; + bool deserializeClusterInfos( Glib::ustring basePath, + Util::IODeserialize& deser ); + + bool serializeFormatInfos( Glib::ustring basePath, + Util::IOSerialize& ser ) const; + bool deserializeFormatInfos( Glib::ustring basePath, + Util::IODeserialize& deser ); + + bool serializePlugVector( Glib::ustring basePath, + Util::IOSerialize& ser, + const PlugVector& vec) const; + bool deserializePlugVector( Glib::ustring basePath, + Util::IODeserialize& deser, + PlugVector& vec ); + +protected: + // Supported stream formats + struct FormatInfo { + FormatInfo() + : m_samplingFrequency( eSF_DontCare ) + , m_isSyncStream( false ) + , m_audioChannels( 0 ) + , m_midiChannels( 0 ) + , m_index( 0xff ) + {} + sampling_frequency_t m_samplingFrequency; + bool m_isSyncStream; + number_of_channels_t m_audioChannels; + number_of_channels_t m_midiChannels; + byte_t m_index; + }; + typedef std::vector FormatInfoVector; + + + Unit* m_unit; + Subunit* m_subunit; + function_block_type_t m_functionBlockType; + function_block_id_t m_functionBlockId; + EPlugAddressType m_addressType; + EPlugDirection m_direction; + plug_id_t m_id; + EPlugType m_infoPlugType; + nr_of_channels_t m_nrOfChannels; + Glib::ustring m_name; + ClusterInfoVector m_clusterInfos; + sampling_frequency_t m_samplingFrequency; + FormatInfoVector m_formatInfos; + PlugVector m_inputConnections; + PlugVector m_outputConnections; + int m_globalId; + static int m_globalIdCounter; + + DECLARE_DEBUG_MODULE; +}; + +const char* avPlugAddressTypeToString( Plug::EPlugAddressType addressType ); +const char* avPlugTypeToString( Plug::EPlugType type ); +const char* avPlugDirectionToString( Plug::EPlugDirection direction ); + +class PlugManager +{ +public: + PlugManager( ); + PlugManager( const PlugManager& rhs ); + ~PlugManager(); + + bool addPlug( Plug& plug ); + bool remPlug( Plug& plug ); + + void showPlugs() const; + + int getPlugCount() + { return m_plugs.size(); }; + + Plug* getPlug( ESubunitType subunitType, + subunit_id_t subunitId, + function_block_type_t functionBlockType, + function_block_id_t functionBlockId, + Plug::EPlugAddressType plugAddressType, + Plug::EPlugDirection plugDirection, + plug_id_t plugId ) const; + Plug* getPlug( int iGlobalId ) const; + PlugVector getPlugsByType( ESubunitType subunitType, + subunit_id_t subunitId, + function_block_type_t functionBlockType, + function_block_id_t functionBlockId, + Plug::EPlugAddressType plugAddressType, + Plug::EPlugDirection plugDirection, + Plug::EPlugType type) const; + + bool serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const; + static PlugManager* deserialize( Glib::ustring basePath, + Util::IODeserialize& deser, + Unit& avDevice ); + void setVerboseLevel( int i ) + {setDebugLevel(i);}; + PlugVector& getPlugs() {return m_plugs;}; + bool tidyPlugConnections(PlugConnectionVector&); + +private: + + PlugVector m_plugs; + + DECLARE_DEBUG_MODULE; +}; + +class PlugConnection { +public: + PlugConnection( Plug& srcPlug, Plug& destPlug ); + + Plug& getSrcPlug() const + { return *m_srcPlug; } + Plug& getDestPlug() const + { return *m_destPlug; } + + bool serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const; + static PlugConnection* deserialize( Glib::ustring basePath, + Util::IODeserialize& deser, + Unit& avDevice ); +private: + PlugConnection(); + +private: + Plug* m_srcPlug; + Plug* m_destPlug; +}; + +typedef std::vector PlugConnectionOwnerVector; + +} + +#endif // AVC_PLUG Index: trunk/libffado/src/libavc/general/avc_generic.cpp =================================================================== --- trunk/libffado/src/libavc/general/avc_generic.cpp (revision 503) +++ trunk/libffado/src/libavc/general/avc_generic.cpp (revision 503) @@ -0,0 +1,338 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_generic.h" +#include "../util/avc_serialize.h" +#include "libieee1394/ieee1394service.h" + +#include "debugmodule/debugmodule.h" + +#include + +#define DEBUG_EXTRA_VERBOSE 5 + + +namespace AVC { + +IMPL_DEBUG_MODULE( AVCCommand, AVCCommand, DEBUG_LEVEL_NORMAL ); +IMPL_DEBUG_MODULE( IBusData, IBusData, DEBUG_LEVEL_VERBOSE ); + +int AVCCommand::m_time = 0; + +AVCCommand::AVCCommand( Ieee1394Service& ieee1394service, + opcode_t opcode ) + : m_p1394Service( &ieee1394service ) + , m_nodeId( 0 ) + , m_ctype( eCT_Unknown ) + , m_subunit( 0xff ) + , m_opcode( opcode ) + , m_eResponse( eR_Unknown ) +{ + +} + +bool +AVCCommand::serialize( IOSSerialize& se ) +{ + // XXX \todo improve IOSSerialize::write interface + char* buf; + asprintf( &buf, "AVCCommand ctype ('%s')", + responseToString( static_cast( m_ctype ) ) ); + se.write( m_ctype, buf ); + free( buf ); + + asprintf( &buf, "AVCCommand subunit (subunit_type = %d, subunit_id = %d)", + getSubunitType(), getSubunitId() ); + se.write( m_subunit, buf ); + free( buf ); + + se.write( m_opcode, "AVCCommand opcode" ); + return true; +} + +bool +AVCCommand::deserialize( IISDeserialize& de ) +{ + de.read( &m_ctype ); + de.read( &m_subunit ); + de.read( &m_opcode ); + return true; +} + +bool +AVCCommand::setCommandType( ECommandType commandType ) +{ + m_ctype = commandType; + m_commandType = commandType; + return true; +} + +AVCCommand::ECommandType +AVCCommand::getCommandType() +{ + return m_commandType; +} + +AVCCommand::EResponse +AVCCommand::getResponse() +{ + return m_eResponse; +} + +bool +AVCCommand::setSubunitType(ESubunitType subunitType) +{ + byte_t subT = subunitType; + + m_subunit = ( subT << 3 ) | ( m_subunit & 0x7 ); + return true; +} + +bool +AVCCommand::setNodeId( fb_nodeid_t nodeId ) +{ + m_nodeId = nodeId; + return true; +} + +bool +AVCCommand::setSubunitId(subunit_id_t subunitId) +{ + m_subunit = ( subunitId & 0x7 ) | ( m_subunit & 0xf8 ); + return true; +} + +ESubunitType +AVCCommand::getSubunitType() +{ + return static_cast( ( m_subunit >> 3 ) ); +} + +subunit_id_t +AVCCommand::getSubunitId() +{ + return m_subunit & 0x7; +} + +bool +AVCCommand::setVerbose( int verboseLevel ) +{ + setDebugLevel(verboseLevel); + return true; +} + +int +AVCCommand::getVerboseLevel() +{ + return getDebugLevel(); +} + + +void +AVCCommand::showFcpFrame( const unsigned char* buf, + unsigned short frameSize ) const +{ + // use an intermediate buffer to avoid a load of very small print's that cause the + // message ringbuffer to overflow + char msg[DEBUG_MAX_MESSAGE_LENGTH]; + int chars_written=0; + for ( int i = 0; i < frameSize; ++i ) { + if ( ( i % 16 ) == 0 ) { + if ( i > 0 ) { + debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "%s\n", msg); + chars_written=0; + } + chars_written+=snprintf(msg+chars_written,DEBUG_MAX_MESSAGE_LENGTH-chars_written," %3d:\t", i );; + } else if ( ( i % 4 ) == 0 ) { + chars_written+=snprintf(msg+chars_written,DEBUG_MAX_MESSAGE_LENGTH-chars_written," "); + } + chars_written+=snprintf(msg+chars_written,DEBUG_MAX_MESSAGE_LENGTH-chars_written, "%02x ", buf[i] ); + } + if (chars_written != 0) { + debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "%s\n", msg ); + } else { + debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "\n" ); + } +} + +bool +AVCCommand::fire() +{ + memset( &m_fcpFrame, 0x0, sizeof( m_fcpFrame ) ); + + BufferSerialize se( m_fcpFrame, sizeof( m_fcpFrame ) ); + if ( !serialize( se ) ) { + debugFatal( "fire: Could not serialize\n" ); + return false; + } + + unsigned short fcpFrameSize = se.getNrOfProducesBytes(); + + if (getDebugLevel() >= DEBUG_LEVEL_VERY_VERBOSE) { + debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE, "%s:\n", getCmdName() ); + debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE, " Request:\n"); + showFcpFrame( m_fcpFrame, fcpFrameSize ); + + StringSerializer se_dbg; + serialize( se_dbg ); + + // output the debug message in smaller chunks to avoid problems + // with a max message size + unsigned int chars_to_write=se_dbg.getString().size(); + unsigned int chars_written=0; + while (chars_writtentransactionBlock( m_nodeId, + (quadlet_t*)m_fcpFrame, + ( fcpFrameSize+3 ) / 4, + &resp_len ); + bool result = false; + if ( resp ) { + resp_len *= 4; + unsigned char* buf = ( unsigned char* ) resp; + + m_eResponse = ( EResponse )( *buf ); + switch ( m_eResponse ) + { + case eR_Accepted: + case eR_Implemented: + case eR_Rejected: + case eR_NotImplemented: + { + BufferDeserialize de( buf, resp_len ); + result = deserialize( de ); + + debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE," Response:\n"); + showFcpFrame( buf, de.getNrOfConsumedBytes() ); + + StringSerializer se_dbg; + serialize( se_dbg ); + + // output the debug message in smaller chunks to avoid problems + // with a max message size + unsigned int chars_to_write=se_dbg.getString().size(); + unsigned int chars_written=0; + while (chars_writtentransactionBlockClose(); + + usleep( m_time ); + + return result; +} + +void +AVCCommand::setSleepAfterAVCCommand( int time ) +{ + m_time = time; +} + +const char* subunitTypeStrings[] = +{ + "Monitor", + "Audio", + "Printer", + "Disc recorder", + "Tape recorder/VCR", + "Tuner", + "CA", + "Video camera", + "unknown", + "Panel", + "Bulletin board", + "Camera storage", + "Music", +}; + +const char* +subunitTypeToString( subunit_type_t subunitType ) +{ + if ( subunitType == eST_Unit ) { + return "Unit"; + } + if ( subunitType > ( int ) ( sizeof( subunitTypeStrings ) + / sizeof( subunitTypeStrings[0] ) ) ) { + return "unknown"; + } else { + return subunitTypeStrings[subunitType]; + } +} + +const char* responseToStrings[] = +{ + "control", + "status", + "specific inquiry", + "notify", + "general inquiry", + "reserved for future specification", + "reserved for future specification", + "reserved for future specification", + "not implemented", + "accepted", + "rejected", + "in transition", + "implemented/stable", + "changed" + "reserved for future specification", + "interim", +}; + +const char* +responseToString( AVCCommand::EResponse eResponse ) +{ + if ( eResponse > ( int )( sizeof( responseToStrings ) / sizeof( responseToStrings[0] ) ) ) { + return "unknown"; + } + return responseToStrings[eResponse]; +} + +} Index: trunk/libffado/src/libavc/general/avc_extended_cmd_generic.cpp =================================================================== --- trunk/libffado/src/libavc/general/avc_extended_cmd_generic.cpp (revision 503) +++ trunk/libffado/src/libavc/general/avc_extended_cmd_generic.cpp (revision 503) @@ -0,0 +1,561 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_extended_cmd_generic.h" +#include "../util/avc_serialize.h" +#include "libieee1394/ieee1394service.h" + +namespace AVC { + +UnitPlugAddress::UnitPlugAddress( EPlugType plugType, plug_type_t plugId ) + : m_plugType( plugType ) + , m_plugId( plugId ) + , m_reserved( 0xff ) +{ +} + +UnitPlugAddress::~UnitPlugAddress() +{ +} + +bool +UnitPlugAddress::serialize( IOSSerialize& se ) +{ + se.write( m_plugType, "UnitPlugAddress plugType" ); + se.write( m_plugId, "UnitPlugAddress plugId" ); + se.write( m_reserved, "UnitPlugAddress reserved" ); + return true; +} + +bool +UnitPlugAddress::deserialize( IISDeserialize& de ) +{ + de.read( &m_plugType ); + de.read( &m_plugId ); + de.read( &m_reserved ); + return true; +} + +UnitPlugAddress* +UnitPlugAddress::clone() const +{ + return new UnitPlugAddress( *this ); +} + +//////////////////////////////////////////////////////////// + +SubunitPlugAddress::SubunitPlugAddress( plug_id_t plugId ) + : m_plugId( plugId ) + , m_reserved0( 0xff ) + , m_reserved1( 0xff ) +{ +} + +SubunitPlugAddress::~SubunitPlugAddress() +{ +} + +bool +SubunitPlugAddress::serialize( IOSSerialize& se ) +{ + se.write( m_plugId, "SubunitPlugAddress plugId" ); + se.write( m_reserved0, "SubunitPlugAddress reserved0" ); + se.write( m_reserved1, "SubunitPlugAddress reserved1" ); + return true; +} + +bool +SubunitPlugAddress::deserialize( IISDeserialize& de ) +{ + de.read( &m_plugId ); + de.read( &m_reserved0 ); + de.read( &m_reserved1 ); + return true; +} + +SubunitPlugAddress* +SubunitPlugAddress::clone() const +{ + return new SubunitPlugAddress( *this ); +} + +//////////////////////////////////////////////////////////// + +FunctionBlockPlugAddress::FunctionBlockPlugAddress( function_block_type_t functionBlockType, + function_block_id_t functionBlockId, + plug_id_t plugId ) + : m_functionBlockType( functionBlockType ) + , m_functionBlockId( functionBlockId ) + , m_plugId( plugId ) +{ +} + +FunctionBlockPlugAddress::~FunctionBlockPlugAddress() +{ +} + +bool +FunctionBlockPlugAddress::serialize( IOSSerialize& se ) +{ + se.write( m_functionBlockType, "FunctionBlockPlugAddress functionBlockType" ); + se.write( m_functionBlockId, "FunctionBlockPlugAddress functionBlockId" ); + se.write( m_plugId, "FunctionBlockPlugAddress plugId" ); + return true; +} + +bool +FunctionBlockPlugAddress::deserialize( IISDeserialize& de ) +{ + de.read( &m_functionBlockType ); + de.read( &m_functionBlockId ); + de.read( &m_plugId ); + return true; +} + +FunctionBlockPlugAddress* +FunctionBlockPlugAddress:: clone() const +{ + return new FunctionBlockPlugAddress( *this ); +} + +//////////////////////////////////////////////////////////// + +UndefinedPlugAddress::UndefinedPlugAddress() + : m_reserved0( 0xff ) + , m_reserved1( 0xff ) + , m_reserved2( 0xff ) +{ +} + +UndefinedPlugAddress::~UndefinedPlugAddress() +{ +} + +bool +UndefinedPlugAddress::serialize( IOSSerialize& se ) +{ + se.write( m_reserved0, "UndefinedPlugAddress reserved0" ); + se.write( m_reserved1, "UndefinedPlugAddress reserved1" ); + se.write( m_reserved2, "UndefinedPlugAddress reserved2" ); + return true; +} + +bool +UndefinedPlugAddress::deserialize( IISDeserialize& de ) +{ + de.read( &m_reserved0 ); + de.read( &m_reserved1 ); + de.read( &m_reserved2 ); + return true; +} + +UndefinedPlugAddress* +UndefinedPlugAddress:: clone() const +{ + return new UndefinedPlugAddress( *this ); +} + +//////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////// + +UnitPlugSpecificDataPlugAddress::UnitPlugSpecificDataPlugAddress( EPlugType plugType, plug_type_t plugId ) + : m_plugType( plugType ) + , m_plugId( plugId ) + , m_reserved0( 0xff ) + , m_reserved1( 0xff ) + , m_reserved2( 0xff ) +{ +} + +UnitPlugSpecificDataPlugAddress::~UnitPlugSpecificDataPlugAddress() +{ +} + +bool +UnitPlugSpecificDataPlugAddress::serialize( IOSSerialize& se ) +{ + se.write( m_plugType, "UnitPlugSpecificDataPlugAddress plugType" ); + se.write( m_plugId, "UnitPlugSpecificDataPlugAddress plugId" ); + se.write( m_reserved0, "UnitPlugSpecificDataPlugAddress reserved0" ); + se.write( m_reserved1, "UnitPlugSpecificDataPlugAddress reserved1" ); + se.write( m_reserved2, "UnitPlugSpecificDataPlugAddress reserved2" ); + return true; +} + +bool +UnitPlugSpecificDataPlugAddress::deserialize( IISDeserialize& de ) +{ + de.read( &m_plugType ); + de.read( &m_plugId ); + de.read( &m_reserved0 ); + de.read( &m_reserved1 ); + de.read( &m_reserved2 ); + return true; +} + +UnitPlugSpecificDataPlugAddress* +UnitPlugSpecificDataPlugAddress::clone() const +{ + return new UnitPlugSpecificDataPlugAddress( *this ); +} + +//////////////////////////////////////////////////////////// + +SubunitPlugSpecificDataPlugAddress::SubunitPlugSpecificDataPlugAddress( + ESubunitType subunitType, + subunit_id_t subunitId, + plug_id_t plugId ) + : m_subunitType( subunitType ) + , m_subunitId( subunitId ) + , m_plugId( plugId ) + , m_reserved0( 0xff ) + , m_reserved1( 0xff ) +{ +} + +SubunitPlugSpecificDataPlugAddress::~SubunitPlugSpecificDataPlugAddress() +{ +} + +bool +SubunitPlugSpecificDataPlugAddress::serialize( IOSSerialize& se ) +{ + se.write( m_subunitType, "SubunitPlugSpecificDataPlugAddress subunitType" ); + se.write( m_subunitId, "SubunitPlugSpecificDataPlugAddress subunitId" ); + se.write( m_plugId, "SubunitPlugSpecificDataPlugAddress plugId" ); + se.write( m_reserved0, "SubunitPlugSpecificDataPlugAddress reserved0" ); + se.write( m_reserved1, "SubunitPlugSpecificDataPlugAddress reserved1" ); + return true; +} + +bool +SubunitPlugSpecificDataPlugAddress::deserialize( IISDeserialize& de ) +{ + de.read( &m_subunitType ); + de.read( &m_subunitId ); + de.read( &m_plugId ); + de.read( &m_reserved0 ); + de.read( &m_reserved1 ); + return true; +} + +SubunitPlugSpecificDataPlugAddress* +SubunitPlugSpecificDataPlugAddress::clone() const +{ + return new SubunitPlugSpecificDataPlugAddress( *this ); +} + +//////////////////////////////////////////////////////////// + +FunctionBlockPlugSpecificDataPlugAddress::FunctionBlockPlugSpecificDataPlugAddress( + ESubunitType subunitType, + subunit_id_t subunitId, + function_block_type_t functionBlockType, + function_block_id_t functionBlockId, + plug_id_t plugId ) + : m_subunitType( subunitType ) + , m_subunitId( subunitId ) + , m_functionBlockType( functionBlockType ) + , m_functionBlockId( functionBlockId ) + , m_plugId( plugId ) +{ +} + +FunctionBlockPlugSpecificDataPlugAddress::~FunctionBlockPlugSpecificDataPlugAddress() +{ +} + +bool +FunctionBlockPlugSpecificDataPlugAddress::serialize( IOSSerialize& se ) +{ + se.write( m_subunitType, "FunctionPlugSpecificDataBlockPlugAddress subunitType" ); + se.write( m_subunitId, "FunctionPlugSpecificDataBlockPlugAddress subunitId" ); + se.write( m_functionBlockType, "FunctionBlockPlugSpecificDataPlugAddress functionBlockType" ); + se.write( m_functionBlockId, "FunctionBlockPlugSpecificDataPlugAddress functionBlockId" ); + se.write( m_plugId, "FunctionBlockPlugSpecificDataPlugAddress plugId" ); + return true; +} + +bool +FunctionBlockPlugSpecificDataPlugAddress::deserialize( IISDeserialize& de ) +{ + de.read( &m_subunitType ); + de.read( &m_subunitId ); + de.read( &m_functionBlockType ); + de.read( &m_functionBlockId ); + de.read( &m_plugId ); + return true; +} + +FunctionBlockPlugSpecificDataPlugAddress* +FunctionBlockPlugSpecificDataPlugAddress:: clone() const +{ + return new FunctionBlockPlugSpecificDataPlugAddress( *this ); +} + +//////////////////////////////////////////////////////////// + +UndefinedPlugSpecificDataPlugAddress::UndefinedPlugSpecificDataPlugAddress() + : m_reserved0( 0xff ) + , m_reserved1( 0xff ) + , m_reserved2( 0xff ) + , m_reserved3( 0xff ) + , m_reserved4( 0xff ) +{ +} + +UndefinedPlugSpecificDataPlugAddress::~UndefinedPlugSpecificDataPlugAddress() +{ +} + +bool +UndefinedPlugSpecificDataPlugAddress::serialize( IOSSerialize& se ) +{ + se.write( m_reserved0, "UndefinedPlugAddress reserved0" ); + se.write( m_reserved1, "UndefinedPlugAddress reserved1" ); + se.write( m_reserved2, "UndefinedPlugAddress reserved2" ); + se.write( m_reserved3, "UndefinedPlugAddress reserved3" ); + se.write( m_reserved4, "UndefinedPlugAddress reserved4" ); + return true; +} + +bool +UndefinedPlugSpecificDataPlugAddress::deserialize( IISDeserialize& de ) +{ + de.read( &m_reserved0 ); + de.read( &m_reserved1 ); + de.read( &m_reserved2 ); + de.read( &m_reserved3 ); + de.read( &m_reserved4 ); + return true; +} + +UndefinedPlugSpecificDataPlugAddress* +UndefinedPlugSpecificDataPlugAddress:: clone() const +{ + return new UndefinedPlugSpecificDataPlugAddress( *this ); +} + +//////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////// + +PlugAddress::PlugAddress( EPlugDirection plugDirection, + EPlugAddressMode plugAddressMode, + UnitPlugAddress& unitPlugAddress ) + : m_plugDirection( plugDirection ) + , m_addressMode( plugAddressMode ) + , m_plugAddressData( new UnitPlugAddress( unitPlugAddress ) ) +{ +} + +PlugAddress::PlugAddress( EPlugDirection plugDirection, + EPlugAddressMode plugAddressMode, + SubunitPlugAddress& subUnitPlugAddress ) + : m_plugDirection( plugDirection ) + , m_addressMode( plugAddressMode ) + , m_plugAddressData( new SubunitPlugAddress( subUnitPlugAddress ) ) +{ +} + +PlugAddress::PlugAddress( EPlugDirection plugDirection, + EPlugAddressMode plugAddressMode, + FunctionBlockPlugAddress& functionBlockPlugAddress ) + : m_plugDirection( plugDirection ) + , m_addressMode( plugAddressMode ) + , m_plugAddressData( new FunctionBlockPlugAddress( functionBlockPlugAddress ) ) +{ +} + +PlugAddress::PlugAddress() + : m_plugDirection( ePD_Undefined ) + , m_addressMode( ePAM_Undefined ) + , m_plugAddressData( new UndefinedPlugAddress() ) +{ +} + +PlugAddress::PlugAddress( const PlugAddress& pa ) + : m_plugDirection( pa.m_plugDirection ) + , m_addressMode( pa.m_addressMode ) + , m_plugAddressData( dynamic_cast( pa.m_plugAddressData->clone() ) ) +{ +} + +PlugAddress::~PlugAddress() +{ + delete m_plugAddressData; + m_plugAddressData = 0; +} + +bool +PlugAddress::serialize( IOSSerialize& se ) +{ + se.write( m_plugDirection, "PlugAddress plugDirection" ); + se.write( m_addressMode, "PlugAddress addressMode" ); + return m_plugAddressData->serialize( se ); +} + +bool +PlugAddress::deserialize( IISDeserialize& de ) +{ + de.read( &m_plugDirection ); + de.read( &m_addressMode ); + return m_plugAddressData->deserialize( de ); +} + +PlugAddress* +PlugAddress::clone() const +{ + return new PlugAddress( *this ); +} + +const char* plugAddressDirectionStrings[] = +{ + "Input", + "Output", + "Undefined", +}; + +const char* plugAddressAddressModeStrings[] = +{ + "Unit", + "Subunit", + "FunctionBlock", + "Undefined", +}; + +const char* +plugAddressPlugDirectionToString( PlugAddress::EPlugDirection direction ) +{ + if ( direction > PlugAddress::ePD_Output ) { + direction = PlugAddress::ePD_Undefined; + } + return plugAddressDirectionStrings[direction]; +} + +const char* +plugAddressAddressModeToString( PlugAddress::EPlugAddressMode mode ) +{ + if ( mode > PlugAddress::ePAM_FunctionBlock ) { + mode = PlugAddress::ePAM_FunctionBlock; + } + return plugAddressAddressModeStrings[mode]; +} + + +//////////////////////////////////////////////////////////// + +PlugAddressSpecificData::PlugAddressSpecificData( EPlugDirection plugDirection, + EPlugAddressMode plugAddressMode, + UnitPlugSpecificDataPlugAddress& unitPlugAddress ) + : m_plugDirection( plugDirection ) + , m_addressMode( plugAddressMode ) + , m_plugAddressData( new UnitPlugSpecificDataPlugAddress( unitPlugAddress ) ) +{ +} + +PlugAddressSpecificData::PlugAddressSpecificData( EPlugDirection plugDirection, + EPlugAddressMode plugAddressMode, + SubunitPlugSpecificDataPlugAddress& subUnitPlugAddress ) + : m_plugDirection( plugDirection ) + , m_addressMode( plugAddressMode ) + , m_plugAddressData( new SubunitPlugSpecificDataPlugAddress( subUnitPlugAddress ) ) +{ +} + +PlugAddressSpecificData::PlugAddressSpecificData( EPlugDirection plugDirection, + EPlugAddressMode plugAddressMode, + FunctionBlockPlugSpecificDataPlugAddress& functionBlockPlugAddress ) + : m_plugDirection( plugDirection ) + , m_addressMode( plugAddressMode ) + , m_plugAddressData( new FunctionBlockPlugSpecificDataPlugAddress( functionBlockPlugAddress ) ) +{ +} + +PlugAddressSpecificData::PlugAddressSpecificData( const PlugAddressSpecificData& pa ) + : m_plugDirection( pa.m_plugDirection ) + , m_addressMode( pa.m_addressMode ) + , m_plugAddressData( dynamic_cast( pa.m_plugAddressData->clone() ) ) +{ +} + +PlugAddressSpecificData::~PlugAddressSpecificData() +{ + delete m_plugAddressData; + m_plugAddressData = 0; +} + +bool +PlugAddressSpecificData::serialize( IOSSerialize& se ) +{ + se.write( m_plugDirection, "PlugAddressSpecificData plugDirection" ); + se.write( m_addressMode, "PlugAddressSpecificData addressMode" ); + return m_plugAddressData->serialize( se ); +} + +bool +PlugAddressSpecificData::deserialize( IISDeserialize& de ) +{ + de.read( &m_plugDirection ); + de.read( &m_addressMode ); + if ( m_plugAddressData ) { + delete m_plugAddressData; + m_plugAddressData = 0; + } + switch ( m_addressMode ) { + case ePAM_Unit: + m_plugAddressData = + new UnitPlugSpecificDataPlugAddress( + UnitPlugSpecificDataPlugAddress::ePT_PCR, + 0xff ); + break; + case ePAM_Subunit: + m_plugAddressData = + new SubunitPlugSpecificDataPlugAddress( + eST_Reserved, + 0xff, + 0xff ); + break; + case ePAM_FunctionBlock: + m_plugAddressData = + new FunctionBlockPlugSpecificDataPlugAddress( + eST_Reserved, + 0xff, + 0xff, + 0xff, + 0xff); + break; + default: + m_plugAddressData = + new UndefinedPlugSpecificDataPlugAddress(); + } + + return m_plugAddressData->deserialize( de ); +} + +PlugAddressSpecificData* +PlugAddressSpecificData::clone() const +{ + return new PlugAddressSpecificData( *this ); +} + +} Index: trunk/libffado/src/libavc/general/avc_unit.cpp =================================================================== --- trunk/libffado/src/libavc/general/avc_unit.cpp (revision 554) +++ trunk/libffado/src/libavc/general/avc_unit.cpp (revision 554) @@ -0,0 +1,975 @@ +/* + * Copyright (C) 2007 by Pieter Palmers + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_unit.h" +#include "avc_subunit.h" +#include "avc_plug.h" + +#include "libieee1394/configrom.h" +#include "libieee1394/ieee1394service.h" + +#include "../general/avc_plug_info.h" +#include "../general/avc_extended_plug_info.h" +#include "../general/avc_subunit_info.h" +#include "../streamformat/avc_extended_stream_format.h" +#include "../util/avc_serialize.h" +#include "../avc_definitions.h" + +#include "debugmodule/debugmodule.h" + +#include +#include + +namespace AVC { + +IMPL_DEBUG_MODULE( Unit, Unit, DEBUG_LEVEL_VERBOSE ); + +Unit::Unit( ) + : m_pPlugManager( new PlugManager( ) ) + , m_activeSyncInfo( 0 ) +{ + debugOutput( DEBUG_LEVEL_VERBOSE, "Created Unit\n" ); + m_pPlugManager->setVerboseLevel( getDebugLevel() ); +} + +Unit::~Unit() +{ + for ( SubunitVector::iterator it = m_subunits.begin(); + it != m_subunits.end(); + ++it ) + { + delete *it; + } + for ( PlugConnectionVector::iterator it = m_plugConnections.begin(); + it != m_plugConnections.end(); + ++it ) + { + delete *it; + } + for ( PlugVector::iterator it = m_pcrPlugs.begin(); + it != m_pcrPlugs.end(); + ++it ) + { + delete *it; + } + for ( PlugVector::iterator it = m_externalPlugs.begin(); + it != m_externalPlugs.end(); + ++it ) + { + delete *it; + } +} + +Plug * +Unit::createPlug( Unit* unit, + Subunit* subunit, + function_block_type_t functionBlockType, + function_block_type_t functionBlockId, + Plug::EPlugAddressType plugAddressType, + Plug::EPlugDirection plugDirection, + plug_id_t plugId ) +{ + + return new Plug( unit, + subunit, + functionBlockType, + functionBlockId, + plugAddressType, + plugDirection, + plugId ); +} + +Subunit* +Unit::createSubunit(Unit& unit, + ESubunitType type, + subunit_t id ) +{ + switch (type) { + case eST_Audio: + return new SubunitAudio(unit, id ); + case eST_Music: + return new SubunitMusic(unit, id ); + default: + return NULL; + } +} + +void +Unit::setVerboseLevel(int l) +{ + m_pPlugManager->setVerboseLevel(l); +} + +bool +Unit::discover() +{ + + if ( !enumerateSubUnits() ) { + debugError( "Could not enumarate sub units\n" ); + return false; + } + + if ( !discoverPlugs() ) { + debugError( "Detecting plugs failed\n" ); + return false; + } + + if ( !discoverPlugConnections() ) { + debugError( "Detecting plug connections failed\n" ); + return false; + } + + if ( !discoverSubUnitsPlugConnections() ) { + debugError( "Detecting subunit plug connnections failed\n" ); + return false; + } + + if ( !m_pPlugManager->tidyPlugConnections(m_plugConnections) ) { + debugError( "Tidying of plug connnections failed\n" ); + return false; + } + + if ( !discoverSyncModes() ) { + debugError( "Detecting sync modes failed\n" ); + return false; + } + + if ( !propagatePlugInfo() ) { + debugError( "Failed to propagate plug info\n" ); + return false; + } + + return true; +} + +bool +Unit::enumerateSubUnits() +{ + SubUnitInfoCmd subUnitInfoCmd( get1394Service() ); + subUnitInfoCmd.setCommandType( AVCCommand::eCT_Status ); + + // NOTE: BeBoB has always exactly one audio and one music subunit. This + // means is fits into the first page of the SubUnitInfo command. + // So there is no need to do more than needed + // FIXME: to be fully spec compliant this needs to be fixed, but let's not + // do that for now + + subUnitInfoCmd.m_page = 0; + subUnitInfoCmd.setNodeId( getConfigRom().getNodeId() ); + subUnitInfoCmd.setVerbose( getDebugLevel() ); + if ( !subUnitInfoCmd.fire() ) { + debugError( "Subunit info command failed\n" ); + // shouldn't this be an error situation? + return false; + } + + for ( int i = 0; i < subUnitInfoCmd.getNrOfValidEntries(); ++i ) { + subunit_type_t subunit_type + = subUnitInfoCmd.m_table[i].m_subunit_type; + + unsigned int subunitId = getNrOfSubunits( subunit_type ); + + debugOutput( DEBUG_LEVEL_VERBOSE, + "subunit_id = %2d, subunit_type = %2d (%s)\n", + subunitId, + subunit_type, + subunitTypeToString( subunit_type ) ); + + Subunit* subunit = 0; + switch( subunit_type ) { + case eST_Audio: + subunit = createSubunit( *this, eST_Audio, subunitId ); + if ( !subunit ) { + debugFatal( "Could not allocate SubunitAudio\n" ); + return false; + } + + subunit->setVerboseLevel(getDebugLevel()); + + if ( !subunit->discover() ) { + debugError( "enumerateSubUnits: Could not discover " + "subunit_id = %2d, subunit_type = %2d (%s)\n", + subunitId, + subunit_type, + subunitTypeToString( subunit_type ) ); + delete subunit; + return false; + } else { + m_subunits.push_back( subunit ); + } + + break; + case eST_Music: + subunit = createSubunit( *this, eST_Music, subunitId ); + if ( !subunit ) { + debugFatal( "Could not allocate SubunitMusic\n" ); + return false; + } + + subunit->setVerboseLevel(getDebugLevel()); + + if ( !subunit->discover() ) { + debugError( "enumerateSubUnits: Could not discover " + "subunit_id = %2d, subunit_type = %2d (%s)\n", + subunitId, + subunit_type, + subunitTypeToString( subunit_type ) ); + delete subunit; + return false; + } else { + m_subunits.push_back( subunit ); + } + + break; + default: + debugOutput( DEBUG_LEVEL_NORMAL, + "Unsupported subunit found, subunit_type = %d (%s)\n", + subunit_type, + subunitTypeToString( subunit_type ) ); + continue; + + } + } + + return true; +} + +Subunit* +Unit::getSubunit( subunit_type_t subunitType, + subunit_id_t subunitId ) const +{ + for ( SubunitVector::const_iterator it = m_subunits.begin(); + it != m_subunits.end(); + ++it ) + { + Subunit* subunit = *it; + if ( ( subunitType == subunit->getSubunitType() ) + && ( subunitId == subunit->getSubunitId() ) ) + { + return subunit; + } + } + + return 0; +} + +unsigned int +Unit::getNrOfSubunits( subunit_type_t subunitType ) const +{ + unsigned int nrOfSubunits = 0; + + for ( SubunitVector::const_iterator it = m_subunits.begin(); + it != m_subunits.end(); + ++it ) + { + Subunit* subunit = *it; + if ( subunitType == subunit->getSubunitType() ) { + nrOfSubunits++; + } + } + + return nrOfSubunits; +} + +bool +Unit::discoverPlugs() +{ + debugOutput( DEBUG_LEVEL_NORMAL, "Discovering plugs...\n"); + + ////////////////////////////////////////////// + // Get number of available isochronous input + // and output plugs of unit + + PlugInfoCmd plugInfoCmd( get1394Service() ); + plugInfoCmd.setNodeId( getConfigRom().getNodeId() ); + plugInfoCmd.setCommandType( AVCCommand::eCT_Status ); + plugInfoCmd.setVerbose( getDebugLevel() ); + + if ( !plugInfoCmd.fire() ) { + debugError( "plug info command failed\n" ); + return false; + } + + debugOutput( DEBUG_LEVEL_NORMAL, "number of iso input plugs = %d\n", + plugInfoCmd.m_serialBusIsochronousInputPlugs ); + debugOutput( DEBUG_LEVEL_NORMAL, "number of iso output plugs = %d\n", + plugInfoCmd.m_serialBusIsochronousOutputPlugs ); + debugOutput( DEBUG_LEVEL_NORMAL, "number of external input plugs = %d\n", + plugInfoCmd.m_externalInputPlugs ); + debugOutput( DEBUG_LEVEL_NORMAL, "number of external output plugs = %d\n", + plugInfoCmd.m_externalOutputPlugs ); + + if ( !discoverPlugsPCR( Plug::eAPD_Input, + plugInfoCmd.m_serialBusIsochronousInputPlugs ) ) + { + debugError( "pcr input plug discovering failed\n" ); + return false; + } + + if ( !discoverPlugsPCR( Plug::eAPD_Output, + plugInfoCmd.m_serialBusIsochronousOutputPlugs ) ) + { + debugError( "pcr output plug discovering failed\n" ); + return false; + } + + if ( !discoverPlugsExternal( Plug::eAPD_Input, + plugInfoCmd.m_externalInputPlugs ) ) + { + debugError( "external input plug discovering failed\n" ); + return false; + } + + if ( !discoverPlugsExternal( Plug::eAPD_Output, + plugInfoCmd.m_externalOutputPlugs ) ) + { + debugError( "external output plug discovering failed\n" ); + return false; + } + + return true; +} + +bool +Unit::discoverPlugsPCR( Plug::EPlugDirection plugDirection, + plug_id_t plugMaxId ) +{ + debugOutput( DEBUG_LEVEL_NORMAL, "Discovering PCR plugs, direction %d...\n",plugDirection); + for ( int plugId = 0; + plugId < plugMaxId; + ++plugId ) + { + Plug* plug = createPlug( this, + NULL, + 0xff, + 0xff, + Plug::eAPA_PCR, + plugDirection, + plugId ); + if ( !plug || !plug->discover() ) { + debugError( "plug discovering failed\n" ); + delete plug; + return false; + } + + debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n", + plug->getName() ); + m_pcrPlugs.push_back( plug ); + } + + return true; +} + +bool +Unit::discoverPlugsExternal( Plug::EPlugDirection plugDirection, + plug_id_t plugMaxId ) +{ + debugOutput( DEBUG_LEVEL_NORMAL, "Discovering External plugs, direction %d...\n",plugDirection); + for ( int plugId = 0; + plugId < plugMaxId; + ++plugId ) + { + Plug* plug = createPlug( this, NULL, + 0xff, + 0xff, + Plug::eAPA_ExternalPlug, + plugDirection, + plugId ); + if ( !plug || !plug->discover() ) { + debugError( "plug discovering failed\n" ); + return false; + } + + debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n", + plug->getName() ); + m_externalPlugs.push_back( plug ); + } + + return true; +} + +bool +Unit::discoverPlugConnections() +{ + debugOutput( DEBUG_LEVEL_NORMAL, "Discovering PCR plug connections...\n"); + for ( PlugVector::iterator it = m_pcrPlugs.begin(); + it != m_pcrPlugs.end(); + ++it ) + { + Plug* plug = *it; + if ( !plug->discoverConnections() ) { + debugError( "Could not discover PCR plug connections\n" ); + return false; + } + } + debugOutput( DEBUG_LEVEL_NORMAL, "Discovering External plug connections...\n"); + for ( PlugVector::iterator it = m_externalPlugs.begin(); + it != m_externalPlugs.end(); + ++it ) + { + Plug* plug = *it; + if ( !plug->discoverConnections() ) { + debugError( "Could not discover External plug connections\n" ); + return false; + } + } + + return true; +} + +bool +Unit::discoverSubUnitsPlugConnections() +{ + for ( SubunitVector::iterator it = m_subunits.begin(); + it != m_subunits.end(); + ++it ) + { + Subunit* subunit = *it; + + if ( !subunit->discoverConnections() ) { + debugError( "Subunit '%s' plug connections failed\n", + subunit->getName() ); + return false; + } + } + return true; +} + +bool +Unit::propagatePlugInfo() +{ + debugOutput( DEBUG_LEVEL_NORMAL, "Propagating info to PCR plugs...\n"); + for ( PlugVector::iterator it = m_pcrPlugs.begin(); + it != m_pcrPlugs.end(); + ++it ) + { + Plug* plug = *it; + debugOutput( DEBUG_LEVEL_NORMAL, "plug: %s\n", plug->getName()); + if (!plug->propagateFromConnectedPlug()) { + debugWarning( "Could not propagate info for plug '%s'\n", plug->getName()); + } + } + debugOutput( DEBUG_LEVEL_NORMAL, "Propagating info to External plugs...\n"); + for ( PlugVector::iterator it = m_externalPlugs.begin(); + it != m_externalPlugs.end(); + ++it ) + { + Plug* plug = *it; + debugOutput( DEBUG_LEVEL_NORMAL, "plug: %s\n", plug->getName()); + if (!plug->propagateFromConnectedPlug()) { + debugWarning( "Could not propagate info for plug '%s'\n", plug->getName()); + } + } + + return true; + +} + + +PlugConnection* +Unit::getPlugConnection( Plug& srcPlug ) const +{ + for ( PlugConnectionVector::const_iterator it + = m_plugConnections.begin(); + it != m_plugConnections.end(); + ++it ) + { + PlugConnection* plugConnection = *it; + if ( &( plugConnection->getSrcPlug() ) == &srcPlug ) { + return plugConnection; + } + } + + return 0; +} + +Plug* +Unit::getPlugById( PlugVector& plugs, + Plug::EPlugDirection plugDirection, + int id ) +{ + for ( PlugVector::iterator it = plugs.begin(); + it != plugs.end(); + ++it ) + { + Plug* plug = *it; + if ( ( id == plug->getPlugId() ) + && ( plugDirection == plug->getPlugDirection() ) ) + { + return plug; + } + } + + return 0; +} + +PlugVector +Unit::getPlugsByType( PlugVector& plugs, + Plug::EPlugDirection plugDirection, + Plug::EPlugType type) +{ + PlugVector plugVector; + for ( PlugVector::iterator it = plugs.begin(); + it != plugs.end(); + ++it ) + { + Plug* plug = *it; + if ( ( type == plug->getPlugType() ) + && ( plugDirection == plug->getPlugDirection() ) ) + { + plugVector.push_back( plug ); + } + } + + return plugVector; +} + +Plug* +Unit::getSyncPlug( int maxPlugId, Plug::EPlugDirection ) +{ + return 0; +} + +bool +Unit::discoverSyncModes() +{ + // Following possible sync plugs exists: + // - Music subunit sync output plug = internal sync (CSP) + // - Unit input plug 0 = SYT match + // - Unit input plut 1 = Sync stream + // + // If last sync mode is reported it is mostelikely not + // implemented *sic* + // + // Following sync sources are device specific: + // - All unit external input plugs which have a + // sync information (WS, SPDIF, ...) + + // First we have to find the sync input and output plug + // in the music subunit. + + // Note PCR input means 1394bus-to-device where as + // MSU input means subunit-to-device + + PlugVector syncPCRInputPlugs = getPlugsByType( m_pcrPlugs, + Plug::eAPD_Input, + Plug::eAPT_Sync ); + if ( !syncPCRInputPlugs.size() ) { + debugWarning( "No PCR sync input plug found\n" ); + } + + PlugVector syncPCROutputPlugs = getPlugsByType( m_pcrPlugs, + Plug::eAPD_Output, + Plug::eAPT_Sync ); + if ( !syncPCROutputPlugs.size() ) { + debugWarning( "No PCR sync output plug found\n" ); + } + + PlugVector isoPCRInputPlugs = getPlugsByType( m_pcrPlugs, + Plug::eAPD_Input, + Plug::eAPT_IsoStream ); + if ( !isoPCRInputPlugs.size() ) { + debugWarning( "No PCR iso input plug found\n" ); + + } + + PlugVector isoPCROutputPlugs = getPlugsByType( m_pcrPlugs, + Plug::eAPD_Output, + Plug::eAPT_IsoStream ); + if ( !isoPCROutputPlugs.size() ) { + debugWarning( "No PCR iso output plug found\n" ); + + } + + PlugVector digitalExternalInputPlugs = getPlugsByType( m_externalPlugs, + Plug::eAPD_Input, + Plug::eAPT_Digital ); + if ( !digitalExternalInputPlugs.size() ) { + debugOutput( DEBUG_LEVEL_VERBOSE, "No external digital input plugs found\n" ); + + } + + PlugVector syncExternalInputPlugs = getPlugsByType( m_externalPlugs, + Plug::eAPD_Input, + Plug::eAPT_Sync ); + if ( !syncExternalInputPlugs.size() ) { + debugOutput( DEBUG_LEVEL_VERBOSE, "No external sync input plugs found\n" ); + + } + + PlugVector syncMSUInputPlugs = m_pPlugManager->getPlugsByType( + eST_Music, + 0, + 0xff, + 0xff, + Plug::eAPA_SubunitPlug, + Plug::eAPD_Input, + Plug::eAPT_Sync ); + if ( !syncMSUInputPlugs.size() ) { + debugWarning( "No sync input plug for MSU subunit found\n" ); + } + + PlugVector syncMSUOutputPlugs = m_pPlugManager->getPlugsByType( + eST_Music, + 0, + 0xff, + 0xff, + Plug::eAPA_SubunitPlug, + Plug::eAPD_Output, + Plug::eAPT_Sync ); + if ( !syncMSUOutputPlugs.size() ) { + debugWarning( "No sync output plug for MSU subunit found\n" ); + } + + debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Sync Input Plugs:\n" ); + showPlugs( syncPCRInputPlugs ); + debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Sync Output Plugs:\n" ); + showPlugs( syncPCROutputPlugs ); + debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Iso Input Plugs:\n" ); + showPlugs( isoPCRInputPlugs ); + debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Iso Output Plugs:\n" ); + showPlugs( isoPCROutputPlugs ); + debugOutput( DEBUG_LEVEL_VERBOSE, "External digital Input Plugs:\n" ); + showPlugs( digitalExternalInputPlugs ); + debugOutput( DEBUG_LEVEL_VERBOSE, "External sync Input Plugs:\n" ); + showPlugs( syncExternalInputPlugs ); + debugOutput( DEBUG_LEVEL_VERBOSE, "MSU Sync Input Plugs:\n" ); + showPlugs( syncMSUInputPlugs ); + debugOutput( DEBUG_LEVEL_VERBOSE, "MSU Sync Output Plugs:\n" ); + showPlugs( syncMSUOutputPlugs ); + + // Check all possible PCR input to MSU input connections + // -> sync stream input + checkSyncConnectionsAndAddToList( syncPCRInputPlugs, + syncMSUInputPlugs, + "Sync Stream Input" ); + + // Check all possible MSU output to PCR output connections + // -> sync stream output + checkSyncConnectionsAndAddToList( syncMSUOutputPlugs, + syncPCROutputPlugs, + "Sync Stream Output" ); + + // Check all PCR iso input to MSU input connections + // -> SYT match + checkSyncConnectionsAndAddToList( isoPCRInputPlugs, + syncMSUInputPlugs, + "Syt Match" ); + + // Check all MSU sync output to MSU input connections + // -> CSP + checkSyncConnectionsAndAddToList( syncMSUOutputPlugs, + syncMSUInputPlugs, + "Internal (CSP)" ); + + // Check all external digital input to MSU input connections + // -> SPDIF/ADAT sync + checkSyncConnectionsAndAddToList( digitalExternalInputPlugs, + syncMSUInputPlugs, + "Digital Input Sync" ); + + // Check all external sync input to MSU input connections + // -> SPDIF/ADAT sync + checkSyncConnectionsAndAddToList( syncExternalInputPlugs, + syncMSUInputPlugs, + "Digital Input Sync" ); + + // Currently active connection signal source cmd, command type + // status, source unknown, destination MSU sync input plug + + for ( PlugVector::const_iterator it = syncMSUInputPlugs.begin(); + it != syncMSUInputPlugs.end(); + ++it ) + { + AVC::Plug* msuPlug = *it; + for ( PlugVector::const_iterator jt = + msuPlug->getInputConnections().begin(); + jt != msuPlug->getInputConnections().end(); + ++jt ) + { + AVC::Plug* plug = *jt; + + for ( SyncInfoVector::iterator it = m_syncInfos.begin(); + it != m_syncInfos.end(); + ++it ) + { + SyncInfo* pSyncInfo = &*it; + if ( ( pSyncInfo->m_source == plug ) + && ( pSyncInfo->m_destination == msuPlug ) ) + { + m_activeSyncInfo = pSyncInfo; + break; + } + } + debugOutput( DEBUG_LEVEL_NORMAL, + "Active Sync Connection: '%s' -> '%s'\n", + plug->getName(), + msuPlug->getName() ); + } + } + + return true; +} + +bool +Unit::checkSyncConnectionsAndAddToList( PlugVector& plhs, + PlugVector& prhs, + std::string syncDescription ) +{ + for ( PlugVector::iterator plIt = plhs.begin(); + plIt != plhs.end(); + ++plIt ) + { + AVC::Plug* pl = *plIt; + for ( PlugVector::iterator prIt = prhs.begin(); + prIt != prhs.end(); + ++prIt ) + { + AVC::Plug* pr = *prIt; + if ( pl->inquireConnnection( *pr ) ) { + m_syncInfos.push_back( SyncInfo( *pl, *pr, syncDescription ) ); + debugOutput( DEBUG_LEVEL_NORMAL, + "Sync connection '%s' -> '%s'\n", + pl->getName(), + pr->getName() ); + } + } + } + return true; +} + +bool Unit::setActiveSync(const SyncInfo& syncInfo) +{ + return syncInfo.m_source->setConnection( *syncInfo.m_destination ); +} + + +void +Unit::showDevice() +{ + m_pPlugManager->showPlugs(); +} + +void +Unit::showPlugs( PlugVector& plugs ) const +{ + int i = 0; + for ( PlugVector::const_iterator it = plugs.begin(); + it != plugs.end(); + ++it, ++i ) + { + Plug* plug = *it; + debugOutput( DEBUG_LEVEL_VERBOSE, "Plug %d\n", i ); + plug->showPlug(); + } +} + +template bool serializeVector( Glib::ustring path, + Util::IOSerialize& ser, + const T& vec ) +{ + bool result = true; // if vec.size() == 0 + int i = 0; + for ( typename T::const_iterator it = vec.begin(); it != vec.end(); ++it ) { + std::ostringstream strstrm; + strstrm << path << i; + result &= ( *it )->serialize( strstrm.str() + "/", ser ); + i++; + } + return result; +} + +template bool deserializeVector( Glib::ustring path, + Util::IODeserialize& deser, + Unit& unit, + VT& vec ) +{ + int i = 0; + bool bFinished = false; + do { + std::ostringstream strstrm; + strstrm << path << i << "/"; + T* ptr = T::deserialize( strstrm.str(), + deser, + unit ); + if ( ptr ) { + vec.push_back( ptr ); + i++; + } else { + bFinished = true; + } + } while ( !bFinished ); + + return true; +} + +bool +Unit::serializeSyncInfoVector( Glib::ustring basePath, + Util::IOSerialize& ser, + const SyncInfoVector& vec ) +{ + bool result = true; + int i = 0; + + for ( SyncInfoVector::const_iterator it = vec.begin(); + it != vec.end(); + ++it ) + { + const SyncInfo& info = *it; + + std::ostringstream strstrm; + strstrm << basePath << i << "/"; + + result &= ser.write( strstrm.str() + "m_source", info.m_source->getGlobalId() ); + result &= ser.write( strstrm.str() + "m_destination", info.m_destination->getGlobalId() ); + result &= ser.write( strstrm.str() + "m_description", Glib::ustring( info.m_description ) ); + + i++; + } + + return result; +} + +bool +Unit::deserializeSyncInfoVector( Glib::ustring basePath, + Util::IODeserialize& deser, + SyncInfoVector& vec ) +{ + int i = 0; + bool bFinished = false; + do { + bool result; + std::ostringstream strstrm; + strstrm << basePath << i << "/"; + + plug_id_t sourceId; + plug_id_t destinationId; + Glib::ustring description; + + if ( deser.isExisting( strstrm.str() + "m_source" ) ) { + result = deser.read( strstrm.str() + "m_source", sourceId ); + result &= deser.read( strstrm.str() + "m_destination", destinationId ); + result &= deser.read( strstrm.str() + "m_description", description ); + } else { + result = false; + } + + if ( result ) { + SyncInfo syncInfo; + syncInfo.m_source = m_pPlugManager->getPlug( sourceId ); + syncInfo.m_destination = m_pPlugManager->getPlug( destinationId ); + syncInfo.m_description = description; + + vec.push_back( syncInfo ); + i++; + } else { + bFinished = true; + } + } while ( !bFinished ); + + return true; +} + +static bool +deserializePlugUpdateConnections( Glib::ustring path, + Util::IODeserialize& deser, + PlugVector& vec ) +{ + bool result = true; + for ( PlugVector::iterator it = vec.begin(); + it != vec.end(); + ++it ) + { + Plug* pPlug = *it; + result &= pPlug->deserializeUpdate( path, deser ); + } + return result; +} + +bool +Unit::serialize( Glib::ustring basePath, + Util::IOSerialize& ser ) const +{ + + bool result; + result = ser.write( basePath + "m_verboseLevel_unit", getDebugLevel() ); + result &= m_pPlugManager->serialize( basePath + "Plug", ser ); // serialize all av plugs + result &= serializeVector( basePath + "PlugConnection", ser, m_plugConnections ); + result &= serializeVector( basePath + "Subunit", ser, m_subunits ); +#warning this fails after the echoaudio merge +// result &= serializeSyncInfoVector( basePath + "SyncInfo", ser, m_syncInfos ); + + int i = 0; + for ( SyncInfoVector::const_iterator it = m_syncInfos.begin(); + it != m_syncInfos.end(); + ++it ) + { + const SyncInfo& info = *it; + if ( m_activeSyncInfo == &info ) { + result &= ser.write( basePath + "m_activeSyncInfo", i ); + break; + } + i++; + } + + return result; +} + +bool +Unit::deserialize( Glib::ustring basePath, + Util::IODeserialize& deser, + Ieee1394Service& ieee1394Service ) +{ + bool result; + + int verboseLevel; + result = deser.read( basePath + "m_verboseLevel_unit", verboseLevel ); + setDebugLevel( verboseLevel ); + + if (m_pPlugManager) delete m_pPlugManager; + m_pPlugManager = PlugManager::deserialize( basePath + "Plug", deser, *this ); + if ( !m_pPlugManager ) { + return false; + } + + result &= deserializePlugUpdateConnections( basePath + "Plug", deser, m_pcrPlugs ); + result &= deserializePlugUpdateConnections( basePath + "Plug", deser, m_externalPlugs ); + result &= deserializeVector( basePath + "PlugConnnection", deser, *this, m_plugConnections ); + result &= deserializeVector( basePath + "Subunit", deser, *this, m_subunits ); + result &= deserializeSyncInfoVector( basePath + "SyncInfo", deser, m_syncInfos ); + + + unsigned int i; + result &= deser.read( basePath + "m_activeSyncInfo", i ); + + if ( result ) { + if ( i < m_syncInfos.size() ) { + m_activeSyncInfo = &m_syncInfos[i]; + } + } + + return true; +} + +} // end of namespace Index: trunk/libffado/src/libavc/general/avc_generic.h =================================================================== --- trunk/libffado/src/libavc/general/avc_generic.h (revision 503) +++ trunk/libffado/src/libavc/general/avc_generic.h (revision 503) @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVCGENERIC_H +#define AVCGENERIC_H + +#include "../avc_definitions.h" +#include "debugmodule/debugmodule.h" + +#include "fbtypes.h" + +#include + +class Ieee1394Service; + +namespace AVC { + +class IOSSerialize; +class IISDeserialize; + +const int fcpFrameMaxLength = 512; +typedef unsigned char fcp_frame_t[fcpFrameMaxLength]; + +enum EAVCDiscoveryMode { + eDM_BeBoB = 0x00, + eDM_GenericAVC = 0x01, + eDM_Invalid = 0xFF, +}; + +class IBusData { +public: + IBusData() {} + virtual ~IBusData() {} + + virtual bool serialize( IOSSerialize& se ) = 0; + virtual bool deserialize( IISDeserialize& de ) = 0; + + virtual IBusData* clone() const = 0; + +protected: + DECLARE_DEBUG_MODULE; +}; + +class AVCCommand +{ +public: + enum EResponse { + eR_Unknown = 0, + eR_NotImplemented = AVC1394_RESP_NOT_IMPLEMENTED, + eR_Accepted = AVC1394_RESP_ACCEPTED, + eR_Rejected = AVC1394_RESP_REJECTED, + eR_InTransition = AVC1394_RESP_IN_TRANSITION, + eR_Implemented = AVC1394_RESP_IMPLEMENTED, + eR_Changed = AVC1394_RESP_CHANGED, + eR_Interim = AVC1394_RESP_INTERIM, + }; + + enum ECommandType { + eCT_Control = AVC1394_CTYP_CONTROL, + eCT_Status = AVC1394_CTYP_STATUS, + eCT_SpecificInquiry = AVC1394_CTYP_SPECIFIC_INQUIRY, + eCT_Notify = AVC1394_CTYP_NOTIFY, + eCT_GeneralInquiry = AVC1394_CTYP_GENERAL_INQUIRY, + eCT_Unknown = 0xff, + }; + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual bool setCommandType( ECommandType commandType ); + virtual bool fire(); + + EResponse getResponse(); + + bool setNodeId( fb_nodeid_t nodeId ); + bool setSubunitType( ESubunitType subunitType ); + bool setSubunitId( subunit_id_t subunitId ); + + ESubunitType getSubunitType(); + subunit_id_t getSubunitId(); + + bool setVerbose( int verboseLevel ); + int getVerboseLevel(); + + virtual const char* getCmdName() const = 0; + + // workaround + static void setSleepAfterAVCCommand( int time ); +protected: + void showFcpFrame( const unsigned char* buf, + unsigned short frameSize ) const; + +protected: + AVCCommand( Ieee1394Service& ieee1394service, opcode_t opcode ); + virtual ~AVCCommand() {} + + ECommandType getCommandType(); + + Ieee1394Service* m_p1394Service; + fb_nodeid_t m_nodeId; + + fcp_frame_t m_fcpFrame; + +private: + ctype_t m_ctype; + subunit_t m_subunit; + opcode_t m_opcode; + EResponse m_eResponse; + ECommandType m_commandType; + static int m_time; + +protected: + DECLARE_DEBUG_MODULE; +}; + + +const char* subunitTypeToString( subunit_type_t subunitType ); +const char* responseToString( AVCCommand::EResponse eResponse ); + +} + +#endif // AVCGENERIC_H Index: trunk/libffado/src/libavc/general/avc_plug_info.cpp =================================================================== --- trunk/libffado/src/libavc/general/avc_plug_info.cpp (revision 503) +++ trunk/libffado/src/libavc/general/avc_plug_info.cpp (revision 503) @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_plug_info.h" +#include "../util/avc_serialize.h" +#include "libieee1394/ieee1394service.h" + +#include +#include + +using namespace std; + +namespace AVC { + +PlugInfoCmd::PlugInfoCmd( Ieee1394Service& ieee1394service, + ESubFunction eSubFunction ) + : AVCCommand( ieee1394service, AVC1394_CMD_PLUG_INFO ) + , m_serialBusIsochronousInputPlugs( 0xff ) + , m_serialBusIsochronousOutputPlugs( 0xff ) + , m_externalInputPlugs( 0xff ) + , m_externalOutputPlugs( 0xff ) + , m_serialBusAsynchronousInputPlugs( 0xff ) + , m_serialBusAsynchronousOuputPlugs( 0xff ) + , m_destinationPlugs( 0xff ) + , m_sourcePlugs( 0xff ) + , m_subFunction( eSubFunction ) +{ +} + +PlugInfoCmd::PlugInfoCmd( const PlugInfoCmd& rhs ) + : AVCCommand( rhs ) + , m_serialBusIsochronousInputPlugs( rhs.m_serialBusIsochronousInputPlugs ) + , m_serialBusIsochronousOutputPlugs( rhs.m_serialBusIsochronousOutputPlugs ) + , m_externalInputPlugs( rhs.m_externalInputPlugs ) + , m_externalOutputPlugs( rhs.m_externalOutputPlugs ) + , m_serialBusAsynchronousInputPlugs( rhs.m_serialBusAsynchronousInputPlugs ) + , m_serialBusAsynchronousOuputPlugs( rhs.m_serialBusAsynchronousOuputPlugs ) + , m_destinationPlugs( rhs.m_destinationPlugs ) + , m_sourcePlugs( rhs.m_sourcePlugs ) + , m_subFunction( rhs.m_subFunction ) +{ +} + +PlugInfoCmd::~PlugInfoCmd() +{ +} + +void +PlugInfoCmd::clear() +{ + m_serialBusIsochronousInputPlugs=0xff; + m_serialBusIsochronousOutputPlugs=0xff; + m_externalInputPlugs=0xff; + m_externalOutputPlugs=0xff; + m_serialBusAsynchronousInputPlugs=0xff; + m_serialBusAsynchronousOuputPlugs=0xff; + m_destinationPlugs=0xff; + m_sourcePlugs=0xff; +} + +bool +PlugInfoCmd::serialize( IOSSerialize& se ) +{ + byte_t reserved = 0xff; + + AVCCommand::serialize( se ); + se.write( m_subFunction, "PlugInfoCmd subFunction" ); + switch( getSubunitType() ) { + case eST_Unit: + switch( m_subFunction ) { + case eSF_SerialBusIsochronousAndExternalPlug: + se.write( m_serialBusIsochronousInputPlugs, "PlugInfoCmd serialBusIsochronousInputPlugs" ); + se.write( m_serialBusIsochronousOutputPlugs, "PlugInfoCmd serialBusIsochronousOutputPlugs" ); + se.write( m_externalInputPlugs, "PlugInfoCmd externalInputPlugs" ); + se.write( m_externalOutputPlugs, "PlugInfoCmd externalOutputPlugs" ); + break; + case eSF_SerialBusAsynchonousPlug: + se.write( m_serialBusAsynchronousInputPlugs, "PlugInfoCmd serialBusAsynchronousInputPlugs" ); + se.write( m_serialBusAsynchronousOuputPlugs, "PlugInfoCmd serialBusAsynchronousOuputPlugs" ); + se.write( reserved, "PlugInfoCmd" ); + se.write( reserved, "PlugInfoCmd" ); + break; + default: + cerr << "Could not serialize with subfucntion " << m_subFunction << endl; + return false; + } + break; + default: + se.write( m_destinationPlugs, "PlugInfoCmd destinationPlugs" ); + se.write( m_sourcePlugs, "PlugInfoCmd sourcePlugs" ); + se.write( reserved, "PlugInfoCmd" ); + se.write( reserved, "PlugInfoCmd" ); + } + return true; +} + +bool +PlugInfoCmd::deserialize( IISDeserialize& de ) +{ + byte_t reserved; + + AVCCommand::deserialize( de ); + de.read( &m_subFunction ); + switch ( getSubunitType() ) { + case eST_Unit: + switch ( m_subFunction ) { + case eSF_SerialBusIsochronousAndExternalPlug: + de.read( &m_serialBusIsochronousInputPlugs ); + de.read( &m_serialBusIsochronousOutputPlugs ); + de.read( &m_externalInputPlugs ); + de.read( &m_externalOutputPlugs ); + break; + case eSF_SerialBusAsynchonousPlug: + de.read( &m_serialBusAsynchronousInputPlugs ); + de.read( &m_serialBusAsynchronousOuputPlugs ); + de.read( &reserved ); + de.read( &reserved ); + break; + default: + cerr << "Could not deserialize with subfunction " << m_subFunction << endl; + return false; + } + break; + default: + de.read( &m_destinationPlugs ); + de.read( &m_sourcePlugs ); + de.read( &reserved ); + de.read( &reserved ); + } + return true; +} + +bool +PlugInfoCmd::setSubFunction( ESubFunction subFunction ) +{ + m_subFunction = subFunction; + return true; +} + +} Index: trunk/libffado/src/libavc/general/avc_extended_subunit_info.cpp =================================================================== --- trunk/libffado/src/libavc/general/avc_extended_subunit_info.cpp (revision 503) +++ trunk/libffado/src/libavc/general/avc_extended_subunit_info.cpp (revision 503) @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_extended_subunit_info.h" +#include "../util/avc_serialize.h" +#include "libieee1394/ieee1394service.h" + +#include + +#define NR_OF_PAGE_DATA 5 +#define SIZE_OF_PAGE_ENTRY 5 + +namespace AVC { + +ExtendedSubunitInfoPageData::ExtendedSubunitInfoPageData() + : IBusData() + , m_functionBlockType( 0xff ) + , m_functionBlockId( 0xff ) + , m_functionBlockSpecialPupose( eSP_NoSpecialPupose ) + , m_noOfInputPlugs( 0xff ) + , m_noOfOutputPlugs( 0xff ) +{ +} + +ExtendedSubunitInfoPageData::~ExtendedSubunitInfoPageData() +{ +} + +bool +ExtendedSubunitInfoPageData::serialize( IOSSerialize& se ) +{ + se.write( m_functionBlockType, "ExtendedSubunitInfoPageData: function block type" ); + se.write( m_functionBlockId, "ExtendedSubunitInfoPageData: function block id" ); + se.write( m_functionBlockSpecialPupose, "ExtendedSubunitInfoPageData: function block special purpose" ); + se.write( m_noOfInputPlugs, "ExtendedSubunitInfoPageData: number of input plugs" ); + se.write( m_noOfOutputPlugs, "ExtendedSubunitInfoPageData: number of output plugs" ); + + return true; +} + +bool +ExtendedSubunitInfoPageData::deserialize( IISDeserialize& de ) +{ + de.read( &m_functionBlockType ); + de.read( &m_functionBlockId ); + de.read( &m_functionBlockSpecialPupose ); + de.read( &m_noOfInputPlugs ); + de.read( &m_noOfOutputPlugs ); + return true; +} + +ExtendedSubunitInfoPageData* +ExtendedSubunitInfoPageData::clone() const +{ + return new ExtendedSubunitInfoPageData( *this ); +} + +////////////////////////////////////////////// + +ExtendedSubunitInfoCmd::ExtendedSubunitInfoCmd( Ieee1394Service& ieee1394service ) + : AVCCommand( ieee1394service, AVC1394_CMD_SUBUNIT_INFO ) + , m_page( 0xff ) + , m_fbType( eFBT_AllFunctinBlockType ) +{ +} + +ExtendedSubunitInfoCmd::ExtendedSubunitInfoCmd( const ExtendedSubunitInfoCmd& rhs ) + : AVCCommand( rhs ) + , m_page( rhs.m_page ) + , m_fbType( rhs.m_fbType ) +{ + for ( ExtendedSubunitInfoPageDataVector::const_iterator it = + rhs.m_infoPageDatas.begin(); + it != rhs.m_infoPageDatas.end(); + ++it ) + { + m_infoPageDatas.push_back( ( *it )->clone() ); + } +} + +ExtendedSubunitInfoCmd::~ExtendedSubunitInfoCmd() +{ + for ( ExtendedSubunitInfoPageDataVector::iterator it = + m_infoPageDatas.begin(); + it != m_infoPageDatas.end(); + ++it ) + { + delete *it; + } +} + +bool +ExtendedSubunitInfoCmd::serialize( IOSSerialize& se ) +{ + bool status = false; + status = AVCCommand::serialize( se ); + status &= se.write( m_page, "ExtendedSubunitInfoCmd: page" ); + status &= se.write( m_fbType, "ExtendedSubunitInfoCmd: function block type" ); + for ( ExtendedSubunitInfoPageDataVector::const_iterator it = + m_infoPageDatas.begin(); + it != m_infoPageDatas.end(); + ++it ) + { + status &= ( *it )->serialize( se ); + } + + int startIndex = m_infoPageDatas.size() * SIZE_OF_PAGE_ENTRY; + int endIndex = SIZE_OF_PAGE_ENTRY * NR_OF_PAGE_DATA; + for ( int i = startIndex; i < endIndex; ++i ) { + byte_t dummy = 0xff; + se.write( dummy, "ExtendedSubunitInfoCmd: space fill" ); + } + return status; +} + +bool +ExtendedSubunitInfoCmd::deserialize( IISDeserialize& de ) +{ + bool status = false; + status = AVCCommand::deserialize( de ); + status &= de.read( &m_page ); + status &= de.read( &m_fbType ); + for ( int i = 0; i < 5; ++i ) { + byte_t next; + de.peek( &next ); + if ( next != 0xff ) { + ExtendedSubunitInfoPageData* infoPageData = + new ExtendedSubunitInfoPageData(); + if ( !infoPageData->deserialize( de ) ) { + return false; + } + m_infoPageDatas.push_back( infoPageData ); + } else { + return status; + } + } + + return status; +} + +} Index: trunk/libffado/src/libavc/general/avc_extended_cmd_generic.h =================================================================== --- trunk/libffado/src/libavc/general/avc_extended_cmd_generic.h (revision 503) +++ trunk/libffado/src/libavc/general/avc_extended_cmd_generic.h (revision 503) @@ -0,0 +1,292 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVCEXTENDEDCMDGENERIC_H +#define AVCEXTENDEDCMDGENERIC_H + +#include "avc_generic.h" + +namespace AVC { + +//////////////////////////////////////////////////////////// + +class PlugAddressData : public IBusData { +}; + +//////////////////////////////////////////////////////////// + +class UnitPlugAddress : public PlugAddressData +{ +public: + enum EPlugType { + ePT_PCR = 0x00, + ePT_ExternalPlug = 0x01, + ePT_AsynchronousPlug = 0x02, + ePT_Unknown = 0xff, + }; + + UnitPlugAddress( EPlugType plugType, plug_type_t plugId ); + virtual ~UnitPlugAddress(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual UnitPlugAddress* clone() const; + + plug_id_t m_plugType; + plug_type_t m_plugId; + reserved_t m_reserved; +}; + +//////////////////////////////////////////////////////////// + +class SubunitPlugAddress : public PlugAddressData +{ +public: + SubunitPlugAddress( plug_id_t plugId ); + virtual ~SubunitPlugAddress(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual SubunitPlugAddress* clone() const; + + plug_id_t m_plugId; + reserved_t m_reserved0; + reserved_t m_reserved1; +}; + + +//////////////////////////////////////////////////////////// + +class FunctionBlockPlugAddress : public PlugAddressData +{ +public: + FunctionBlockPlugAddress( function_block_type_t functionBlockType, + function_block_id_t functionBlockId, + plug_id_t plugId ); + virtual ~FunctionBlockPlugAddress(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual FunctionBlockPlugAddress* clone() const; + + function_block_type_t m_functionBlockType; + function_block_id_t m_functionBlockId; + plug_id_t m_plugId; +}; + +//////////////////////////////////////////////////////////// + +class UndefinedPlugAddress : public PlugAddressData +{ +public: + UndefinedPlugAddress(); + virtual ~UndefinedPlugAddress(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual UndefinedPlugAddress* clone() const; + + reserved_t m_reserved0; + reserved_t m_reserved1; + reserved_t m_reserved2; +}; + +//////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////// + +class UnitPlugSpecificDataPlugAddress : public PlugAddressData +{ +public: + enum EPlugType { + ePT_PCR = 0x00, + ePT_ExternalPlug = 0x01, + ePT_AsynchronousPlug = 0x02, + }; + + UnitPlugSpecificDataPlugAddress( EPlugType plugType, + plug_type_t plugId ); + virtual ~UnitPlugSpecificDataPlugAddress(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual UnitPlugSpecificDataPlugAddress* clone() const; + + plug_type_t m_plugType; + plug_id_t m_plugId; + reserved_t m_reserved0; + reserved_t m_reserved1; + reserved_t m_reserved2; +}; + +//////////////////////////////////////////////////////////// + +class SubunitPlugSpecificDataPlugAddress : public PlugAddressData +{ +public: + SubunitPlugSpecificDataPlugAddress( ESubunitType subunitType, + subunit_id_t subunitId, + plug_id_t plugId ); + virtual ~SubunitPlugSpecificDataPlugAddress(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual SubunitPlugSpecificDataPlugAddress* clone() const; + + subunit_type_t m_subunitType; + subunit_id_t m_subunitId; + plug_id_t m_plugId; + reserved_t m_reserved0; + reserved_t m_reserved1; +}; + +//////////////////////////////////////////////////////////// + +class FunctionBlockPlugSpecificDataPlugAddress : public PlugAddressData +{ +public: + FunctionBlockPlugSpecificDataPlugAddress( ESubunitType subunitType, + subunit_id_t subunitId, + function_block_type_t functionBlockType, + function_block_id_t functionBlockId, + plug_id_t plugId); + virtual ~FunctionBlockPlugSpecificDataPlugAddress(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual FunctionBlockPlugSpecificDataPlugAddress* clone() const; + + subunit_type_t m_subunitType; + subunit_id_t m_subunitId; + function_block_type_t m_functionBlockType; + function_block_id_t m_functionBlockId; + plug_id_t m_plugId; +}; + +//////////////////////////////////////////////////////////// + +class UndefinedPlugSpecificDataPlugAddress : public PlugAddressData +{ +public: + UndefinedPlugSpecificDataPlugAddress(); + virtual ~UndefinedPlugSpecificDataPlugAddress(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual UndefinedPlugSpecificDataPlugAddress* clone() const; + + reserved_t m_reserved0; + reserved_t m_reserved1; + reserved_t m_reserved2; + reserved_t m_reserved3; + reserved_t m_reserved4; +}; + +//////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////// + +class PlugAddress : public IBusData { +public: + enum EPlugDirection { + ePD_Input = 0x00, + ePD_Output = 0x01, + ePD_Undefined = 0xff, + }; + + enum EPlugAddressMode { + ePAM_Unit = 0x00, + ePAM_Subunit = 0x01, + ePAM_FunctionBlock = 0x02, + ePAM_Undefined = 0xff, + }; + + PlugAddress( EPlugDirection plugDirection, + EPlugAddressMode plugAddressMode, + UnitPlugAddress& unitPlugAddress ); + PlugAddress( EPlugDirection plugDirection, + EPlugAddressMode plugAddressMode, + SubunitPlugAddress& subUnitPlugAddress ); + PlugAddress( EPlugDirection plugDirection, + EPlugAddressMode plugAddressMode, + FunctionBlockPlugAddress& functionBlockPlugAddress ); + PlugAddress( ); // undefined plug address + PlugAddress( const PlugAddress& pa ); + + virtual ~PlugAddress(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual PlugAddress* clone() const; + + plug_direction_t m_plugDirection; + plug_address_mode_t m_addressMode; + PlugAddressData* m_plugAddressData; +}; + +const char* plugAddressPlugDirectionToString( PlugAddress::EPlugDirection direction ); +const char* plugAddressAddressModeToString( PlugAddress::EPlugAddressMode mode ); + +//////////////////////////////////////////////////////////// + +class PlugAddressSpecificData : public IBusData { +public: + enum EPlugDirection { + ePD_Input = 0x00, + ePD_Output = 0x01, + }; + + enum EPlugAddressMode { + ePAM_Unit = 0x00, + ePAM_Subunit = 0x01, + ePAM_FunctionBlock = 0x02, + ePAM_Undefined = 0xff, + }; + + PlugAddressSpecificData( EPlugDirection plugDirection, + EPlugAddressMode plugAddressMode, + UnitPlugSpecificDataPlugAddress& unitPlugAddress ); + PlugAddressSpecificData( EPlugDirection plugDirection, + EPlugAddressMode plugAddressMode, + SubunitPlugSpecificDataPlugAddress& subUnitPlugAddress ); + PlugAddressSpecificData( EPlugDirection plugDirection, + EPlugAddressMode plugAddressMode, + FunctionBlockPlugSpecificDataPlugAddress& functionBlockPlugAddress ); + PlugAddressSpecificData( EPlugDirection plugDirection, + EPlugAddressMode plugAddressMode ); + PlugAddressSpecificData( const PlugAddressSpecificData& pa ); + + virtual ~PlugAddressSpecificData(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual PlugAddressSpecificData* clone() const; + + plug_direction_t m_plugDirection; + plug_address_mode_t m_addressMode; + PlugAddressData* m_plugAddressData; +}; + +} + +#endif Index: trunk/libffado/src/libavc/general/avc_unit.h =================================================================== --- trunk/libffado/src/libavc/general/avc_unit.h (revision 554) +++ trunk/libffado/src/libavc/general/avc_unit.h (revision 554) @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2007 by Pieter Palmers + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVC_UNIT_H +#define AVC_UNIT_H + +#include + +#include "debugmodule/debugmodule.h" + +#include "../avc_definitions.h" +#include "../general/avc_extended_cmd_generic.h" +#include "../general/avc_subunit.h" +#include "../general/avc_plug.h" +#include "../musicsubunit/avc_musicsubunit.h" +#include "../audiosubunit/avc_audiosubunit.h" + +#include "libutil/serialize.h" + +#include +#include + +class ConfigRom; +class Ieee1394Service; + +namespace AVC { + +class Unit { +public: + Unit( ); + virtual ~Unit(); + + virtual void setVerboseLevel(int l); + virtual void showDevice(); + + // these have to be implemented by the parent class + /// Returns the 1394 service + virtual Ieee1394Service& get1394Service() = 0; + /// Returns the ConfigRom + virtual ConfigRom& getConfigRom() const = 0; + + /// Discovers the unit's internals + virtual bool discover(); + + PlugManager& getPlugManager() + { return *m_pPlugManager; } + + struct SyncInfo { + SyncInfo( Plug& source, + Plug& destination, + std::string description ) + : m_source( &source ) + , m_destination( &destination ) + , m_description( description ) + {} + SyncInfo() + : m_source( 0 ) + , m_destination( 0 ) + , m_description( "" ) + {} + Plug* m_source; + Plug* m_destination; + std::string m_description; + }; + + typedef std::vector SyncInfoVector; + virtual const SyncInfoVector& getSyncInfos() const + { return m_syncInfos; } + virtual const SyncInfo* getActiveSyncInfo() const + { return m_activeSyncInfo; } + + virtual bool setActiveSync( const SyncInfo& syncInfo ); + + bool serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const; + bool deserialize( Glib::ustring basePath, + Util::IODeserialize& deser, + Ieee1394Service& ieee1394Service ); + SubunitAudio* getAudioSubunit( subunit_id_t subunitId ) + { return dynamic_cast( + getSubunit( AVC1394_SUBUNIT_AUDIO , subunitId ));}; + SubunitMusic* getMusicSubunit( subunit_id_t subunitId ) + { return dynamic_cast( + getSubunit( AVC1394_SUBUNIT_MUSIC , subunitId ));}; + Subunit* getSubunit( subunit_type_t subunitType, + subunit_id_t subunitId ) const; + + virtual AVC::Subunit* createSubunit(Unit& unit, + ESubunitType type, + subunit_t id ); + virtual AVC::Plug* createPlug( AVC::Unit* unit, + AVC::Subunit* subunit, + AVC::function_block_type_t functionBlockType, + AVC::function_block_type_t functionBlockId, + AVC::Plug::EPlugAddressType plugAddressType, + AVC::Plug::EPlugDirection plugDirection, + AVC::plug_id_t plugId ); + +protected: + + virtual bool enumerateSubUnits(); + virtual bool discoverPlugConnections(); + virtual bool discoverSubUnitsPlugConnections(); + virtual bool discoverPlugs(); + virtual bool discoverPlugsPCR( AVC::Plug::EPlugDirection plugDirection, + AVC::plug_id_t plugMaxId ); + virtual bool discoverPlugsExternal( AVC::Plug::EPlugDirection plugDirection, + AVC::plug_id_t plugMaxId ); + virtual bool propagatePlugInfo(); + virtual bool discoverSyncModes(); + virtual bool checkSyncConnectionsAndAddToList( AVC::PlugVector& plhs, + AVC::PlugVector& prhs, + std::string syncDescription ); + virtual Plug* getSyncPlug( int maxPlugId, Plug::EPlugDirection ); + + unsigned int getNrOfSubunits( subunit_type_t subunitType ) const; + PlugConnection* getPlugConnection( Plug& srcPlug ) const; + + Plug* getPlugById( PlugVector& plugs, + Plug::EPlugDirection plugDireciton, + int id ); + PlugVector getPlugsByType( PlugVector& plugs, + Plug::EPlugDirection plugDirection, + Plug::EPlugType type); + +// bool setSamplingFrequencyPlug( Plug& plug, +// Plug::EPlugDirection direction, +// ESamplingFrequency samplingFrequency ); + + void showPlugs( PlugVector& plugs ) const; + + + bool serializeSyncInfoVector( Glib::ustring basePath, + Util::IOSerialize& ser, + const SyncInfoVector& vec ); + bool deserializeSyncInfoVector( Glib::ustring basePath, + Util::IODeserialize& deser, + SyncInfoVector& vec ); +protected: + SubunitVector m_subunits; + PlugVector m_pcrPlugs; + PlugVector m_externalPlugs; + PlugConnectionVector m_plugConnections; + PlugManager* m_pPlugManager; + SyncInfoVector m_syncInfos; + SyncInfo* m_activeSyncInfo; + +private: + DECLARE_DEBUG_MODULE; + +}; + +} + +#endif Index: trunk/libffado/src/libavc/general/avc_signal_format.cpp =================================================================== --- trunk/libffado/src/libavc/general/avc_signal_format.cpp (revision 524) +++ trunk/libffado/src/libavc/general/avc_signal_format.cpp (revision 524) @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_signal_format.h" +#include "../util/avc_serialize.h" +#include "libieee1394/ieee1394service.h" + +#include +#include + +using namespace std; + +namespace AVC { + +OutputPlugSignalFormatCmd::OutputPlugSignalFormatCmd(Ieee1394Service& ieee1394service) + : AVCCommand( ieee1394service, AVC1394_CMD_OUTPUT_PLUG_SIGNAL_FORMAT ) + , m_plug ( 0 ) + , m_eoh ( 1 ) + , m_form ( 0 ) + , m_fmt ( 0 ) +{ + m_fdf[0]=0xFF; + m_fdf[1]=0xFF; + m_fdf[2]=0xFF; +} + +OutputPlugSignalFormatCmd::~OutputPlugSignalFormatCmd() +{ +} + +bool +OutputPlugSignalFormatCmd::serialize( IOSSerialize& se ) +{ + bool result=true; + result &= AVCCommand::serialize( se ); + + result &= se.write(m_plug,"OutputPlugSignalFormatCmd plug"); + + byte_t tmp = ((m_eoh & 0x01)<<7); + tmp |= ((m_form & 0x01)<<6); + tmp |= (m_fmt & 0x3f); + + result &= se.write(tmp,"OutputPlugSignalFormatCmd eoh,form,fmt"); + + result &= se.write(m_fdf[0],"OutputPlugSignalFormatCmd fdf[0]"); + result &= se.write(m_fdf[1],"OutputPlugSignalFormatCmd fdf[1]"); + result &= se.write(m_fdf[2],"OutputPlugSignalFormatCmd fdf[2]"); + + return result; +} + +bool +OutputPlugSignalFormatCmd::deserialize( IISDeserialize& de ) +{ + bool result=true; + result &= AVCCommand::deserialize( de ); + result &= de.read(&m_plug); + + byte_t tmp; + result &= de.read(&tmp); + + m_eoh=((tmp & 0x80)>>7); + m_form=((tmp & 0x40)>>6); + m_fmt=tmp & 0x3f; + + result &= de.read(&m_fdf[0]); + result &= de.read(&m_fdf[1]); + result &= de.read(&m_fdf[2]); + + return result; +} + +//------------------------ + +InputPlugSignalFormatCmd::InputPlugSignalFormatCmd(Ieee1394Service& ieee1394service) + : AVCCommand( ieee1394service, AVC1394_CMD_INPUT_PLUG_SIGNAL_FORMAT ) + , m_plug ( 0 ) + , m_eoh ( 1 ) + , m_form ( 0 ) + , m_fmt ( 0 ) +{ + m_fdf[0]=0xFF; + m_fdf[1]=0xFF; + m_fdf[2]=0xFF; +} + +InputPlugSignalFormatCmd::~InputPlugSignalFormatCmd() +{ +} + +bool +InputPlugSignalFormatCmd::serialize( IOSSerialize& se ) +{ + bool result=true; + result &= AVCCommand::serialize( se ); + + result &= se.write(m_plug,"InputPlugSignalFormatCmd plug"); + + byte_t tmp = ((m_eoh& 0x01)<<7); + tmp |= ((m_form& 0x01)<<6); + tmp |= (m_fmt& 0x3f); + + result &= se.write(tmp,"InputPlugSignalFormatCmd eoh,form,fmt"); + + result &= se.write(m_fdf[0],"InputPlugSignalFormatCmd fdf[0]"); + result &= se.write(m_fdf[1],"InputPlugSignalFormatCmd fdf[1]"); + result &= se.write(m_fdf[2],"InputPlugSignalFormatCmd fdf[2]"); + + return result; +} + +bool +InputPlugSignalFormatCmd::deserialize( IISDeserialize& de ) +{ + bool result=true; + result &= AVCCommand::deserialize( de ); + result &= de.read(&m_plug); + + byte_t tmp; + result &= de.read(&tmp); + + m_eoh=((tmp & 0x80)>>7); + m_form=((tmp & 0x40)>>6); + m_fmt=tmp & 0x3f; + + result &= de.read(&m_fdf[0]); + result &= de.read(&m_fdf[1]); + result &= de.read(&m_fdf[2]); + + return result; +} +} Index: trunk/libffado/src/libavc/general/avc_plug_info.h =================================================================== --- trunk/libffado/src/libavc/general/avc_plug_info.h (revision 503) +++ trunk/libffado/src/libavc/general/avc_plug_info.h (revision 503) @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVCPLUGINFO_H +#define AVCPLUGINFO_H + +#include "avc_generic.h" + +#include + +#define AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_ISOCHRONOUS_AND_EXTERNAL_PLUG 0x00 +#define AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_ASYNCHRONOUS_PLUG 0x01 +#define AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_GENERIC_BUS_PLUG_BLUETOOTH 0x40 +#define AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_NOT_USED 0xFF + + +namespace AVC { + + +class PlugInfoCmd: public AVCCommand +{ +public: + enum ESubFunction { + eSF_SerialBusIsochronousAndExternalPlug = AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_ISOCHRONOUS_AND_EXTERNAL_PLUG, + eSF_SerialBusAsynchonousPlug = AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_ASYNCHRONOUS_PLUG, + eSF_SerialBusPlug = AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_GENERIC_BUS_PLUG_BLUETOOTH, + eSF_NotUsed = AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_NOT_USED, + }; + + PlugInfoCmd( Ieee1394Service& ieee1394service, + ESubFunction eSubFunction = eSF_SerialBusIsochronousAndExternalPlug ); + PlugInfoCmd( const PlugInfoCmd& rhs ); + virtual ~PlugInfoCmd(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual void clear(); + + virtual const char* getCmdName() const + { return "PlugInfoCmd"; } + + nr_of_plugs_t m_serialBusIsochronousInputPlugs; + nr_of_plugs_t m_serialBusIsochronousOutputPlugs; + nr_of_plugs_t m_externalInputPlugs; + nr_of_plugs_t m_externalOutputPlugs; + nr_of_plugs_t m_serialBusAsynchronousInputPlugs; + nr_of_plugs_t m_serialBusAsynchronousOuputPlugs; + nr_of_plugs_t m_destinationPlugs; + nr_of_plugs_t m_sourcePlugs; + + bool setSubFunction( ESubFunction subFunction ); + +protected: + subfunction_t m_subFunction; + +}; + +} + +#endif // AVCPLUGINFO_H Index: trunk/libffado/src/libavc/general/avc_extended_subunit_info.h =================================================================== --- trunk/libffado/src/libavc/general/avc_extended_subunit_info.h (revision 503) +++ trunk/libffado/src/libavc/general/avc_extended_subunit_info.h (revision 503) @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVCEXTENDEDSUBUNITINFO_H +#define AVCEXTENDEDSUBUNITINFO_H + +#include "avc_generic.h" + +#include + +#include +#include + +namespace AVC { + + +class ExtendedSubunitInfoPageData: public IBusData +{ + public: + enum ESpecialPurpose { + eSP_InputGain = 0x00, + eSP_OutputVolume = 0x01, + eSP_NoSpecialPupose = 0xff, + }; + + ExtendedSubunitInfoPageData(); + virtual ~ExtendedSubunitInfoPageData(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + virtual ExtendedSubunitInfoPageData* clone() const; + + function_block_type_t m_functionBlockType; + function_block_id_t m_functionBlockId; + function_block_special_purpose_t m_functionBlockSpecialPupose; + no_of_input_plugs_t m_noOfInputPlugs; + no_of_output_plugs_t m_noOfOutputPlugs; +}; + +typedef std::vector ExtendedSubunitInfoPageDataVector; + +class ExtendedSubunitInfoCmd: public AVCCommand +{ +public: + enum EFunctionBlockType { + eFBT_AllFunctinBlockType = 0xff, + eFBT_AudioSubunitSelector = 0x80, + eFBT_AudioSubunitFeature = 0x81, + eFBT_AudioSubunitProcessing = 0x82, + eFBT_AudioSubunitCodec = 0x83, + }; + + enum EProcessingType { + ePT_Unknown = 0x00, + ePT_Mixer = 0x01, + ePT_Generic = 0x02, + ePT_UpDown = 0x03, + ePT_DolbyProLogic = 0x04, + ePT_3DStereoExtender = 0x05, + ePT_Reverberation = 0x06, + ePT_Chorus = 0x07, + ePT_DynamicRangeCompression = 0x08, + ePT_EnhancedMixer = 0x82, + ePT_Reserved = 0xff, + }; + + enum ECodecType { + eCT_AC3Decoder = 0x01, + eCT_MPEGDecoder = 0x02, + eCT_DTSDecoder = 0x03, + eCT_Reserved = 0xff, + + }; + + ExtendedSubunitInfoCmd( Ieee1394Service& ieee1394service ); + ExtendedSubunitInfoCmd( const ExtendedSubunitInfoCmd& rhs ); + virtual ~ExtendedSubunitInfoCmd(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual const char* getCmdName() const + { return "ExtendedSubunitInfoCmd"; } + + page_t m_page; + function_block_type_t m_fbType; + ExtendedSubunitInfoPageDataVector m_infoPageDatas; +}; + +} + +#endif Index: trunk/libffado/src/libavc/general/avc_connect.cpp =================================================================== --- trunk/libffado/src/libavc/general/avc_connect.cpp (revision 524) +++ trunk/libffado/src/libavc/general/avc_connect.cpp (revision 524) @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_connect.h" +#include "../util/avc_serialize.h" +#include "libieee1394/ieee1394service.h" + +#include +#include + +using namespace std; + +namespace AVC { + +ConnectCmd::ConnectCmd(Ieee1394Service& ieee1394service) + : AVCCommand( ieee1394service, AVC1394_CMD_CONNECT ) +{ +} + +ConnectCmd::~ConnectCmd() +{ +} + +bool +ConnectCmd::serialize( IOSSerialize& se ) +{ + bool result=true; + result &= AVCCommand::serialize( se ); + return result; +} + +bool +ConnectCmd::deserialize( IISDeserialize& de ) +{ + bool result=true; + result &= AVCCommand::deserialize( de ); + return result; +} + +} Index: trunk/libffado/src/libavc/general/avc_subunit.cpp =================================================================== --- trunk/libffado/src/libavc/general/avc_subunit.cpp (revision 554) +++ trunk/libffado/src/libavc/general/avc_subunit.cpp (revision 554) @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2007 by Pieter Palmers + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + + +#include "avc_subunit.h" +#include "../general/avc_unit.h" +#include "../general/avc_plug.h" + +#include "libieee1394/configrom.h" + +#include "../general/avc_plug_info.h" +#include "../streamformat/avc_extended_stream_format.h" +#include "../util/avc_serialize.h" + +#include + +namespace AVC { + +IMPL_DEBUG_MODULE( Subunit, Subunit, DEBUG_LEVEL_VERBOSE ); + +//////////////////////////////////////////// + +Subunit::Subunit( Unit& unit, + ESubunitType type, + subunit_t id ) + : m_unit( &unit ) + , m_sbType( type ) + , m_sbId( id ) +{ + +} + +Subunit::Subunit() +{ +} + +Subunit::~Subunit() +{ + for ( PlugVector::iterator it = m_plugs.begin(); + it != m_plugs.end(); + ++it ) + { + delete *it; + } +} + +Plug * +Subunit::createPlug( AVC::Unit* unit, + AVC::Subunit* subunit, + AVC::function_block_type_t functionBlockType, + AVC::function_block_type_t functionBlockId, + AVC::Plug::EPlugAddressType plugAddressType, + AVC::Plug::EPlugDirection plugDirection, + AVC::plug_id_t plugId ) +{ + + return new Plug( unit, + subunit, + functionBlockType, + functionBlockId, + plugAddressType, + plugDirection, + plugId ); +} + +bool +Subunit::discover() +{ + if ( !discoverPlugs() ) { + debugError( "plug discovery failed\n" ); + return false; + } + + return true; +} + +bool +Subunit::discoverPlugs() +{ + PlugInfoCmd plugInfoCmd( getUnit().get1394Service(), + PlugInfoCmd::eSF_SerialBusIsochronousAndExternalPlug ); + plugInfoCmd.setNodeId( getUnit().getConfigRom().getNodeId() ); + plugInfoCmd.setCommandType( AVCCommand::eCT_Status ); + plugInfoCmd.setSubunitType( getSubunitType() ); + plugInfoCmd.setSubunitId( getSubunitId() ); + plugInfoCmd.setVerbose( getDebugLevel() ); + + if ( !plugInfoCmd.fire() ) { + debugError( "plug info command failed\n" ); + return false; + } + + debugOutput( DEBUG_LEVEL_NORMAL, "number of source plugs = %d\n", + plugInfoCmd.m_sourcePlugs ); + debugOutput( DEBUG_LEVEL_NORMAL, "number of destination output " + "plugs = %d\n", plugInfoCmd.m_destinationPlugs ); + + if ( !discoverPlugs( Plug::eAPD_Input, + plugInfoCmd.m_destinationPlugs ) ) + { + debugError( "destination plug discovering failed\n" ); + return false; + } + + if ( !discoverPlugs( Plug::eAPD_Output, + plugInfoCmd.m_sourcePlugs ) ) + { + debugError( "source plug discovering failed\n" ); + return false; + } + + return true; +} + +bool +Subunit::discoverConnections() +{ + debugOutput(DEBUG_LEVEL_NORMAL, "Discovering connections...\n"); + + for ( PlugVector::iterator it = getPlugs().begin(); + it != getPlugs().end(); + ++it ) + { + Plug* plug = *it; + if ( !plug->discoverConnections() ) { + debugError( "plug connection discovering failed ('%s')\n", + plug->getName() ); + return false; + } + } + + return true; +} + +bool +Subunit::discoverPlugs(Plug::EPlugDirection plugDirection, + plug_id_t plugMaxId ) +{ + debugOutput(DEBUG_LEVEL_NORMAL, "Discovering plugs...\n"); + for ( int plugIdx = 0; + plugIdx < plugMaxId; + ++plugIdx ) + { + Plug* plug = createPlug( &getUnit(), + &getSubunit(), + 0xff, + 0xff, + Plug::eAPA_SubunitPlug, + plugDirection, + plugIdx ); + if ( !plug ) { + debugError( "plug creation failed\n" ); + return false; + } + + plug->setVerboseLevel(getDebugLevel()); + + if ( !plug->discover() ) { + debugError( "plug discover failed\n" ); + return false; + } + + debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n", + plug->getName() ); + getPlugs().push_back( plug ); + } + return true; +} + +bool +Subunit::addPlug( Plug& plug ) +{ + m_plugs.push_back( &plug ); + return true; +} + + +Plug* +Subunit::getPlug(Plug::EPlugDirection direction, plug_id_t plugId) +{ + for ( PlugVector::iterator it = m_plugs.begin(); + it != m_plugs.end(); + ++it ) + { + Plug* plug = *it; + if ( ( plug->getPlugId() == plugId ) + && ( plug->getDirection() == direction ) ) + { + return plug; + } + } + return 0; +} + +bool +Subunit::initPlugFromDescriptor( Plug& plug ) +{ + debugError("plug loading from descriptor not implemented\n"); + return false; +} + +bool +Subunit::serialize( Glib::ustring basePath, + Util::IOSerialize& ser ) const +{ + bool result; + + result = ser.write( basePath + "m_sbType", m_sbType ); + result &= ser.write( basePath + "m_sbId", m_sbId ); + result &= ser.write( basePath + "m_verboseLevel", getDebugLevel() ); + result &= serializeChild( basePath, ser ); + + return result; +} + +Subunit* +Subunit::deserialize( Glib::ustring basePath, + Util::IODeserialize& deser, + Unit& unit ) +{ + bool result; + ESubunitType sbType; + + if ( !deser.isExisting( basePath + "m_sbType" ) ) { + return 0; + } + + result = deser.read( basePath + "m_sbType", sbType ); + + Subunit* pSubunit = 0; + + #warning FIXME: The derived class should be creating these + // FIXME: The derived class should be creating these, such that discover() can become pure virtual + switch( sbType ) { + case eST_Audio: + pSubunit = new SubunitAudio; + break; + case eST_Music: + pSubunit = new SubunitMusic; + break; + default: + pSubunit = 0; + } + + if ( !pSubunit ) { + return 0; + } + + pSubunit->m_unit = &unit; + pSubunit->m_sbType = sbType; + result &= deser.read( basePath + "m_sbId", pSubunit->m_sbId ); + int verboseLevel; + result &= deser.read( basePath + "m_verboseLevel", verboseLevel ); + setDebugLevel(verboseLevel); + result &= pSubunit->deserializeChild( basePath, deser, unit ); + + if ( !result ) { + delete pSubunit; + return 0; + } + + return pSubunit; +} + +} Index: trunk/libffado/src/libavc/general/avc_signal_format.h =================================================================== --- trunk/libffado/src/libavc/general/avc_signal_format.h (revision 524) +++ trunk/libffado/src/libavc/general/avc_signal_format.h (revision 524) @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2007 by Pieter Palmers + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVCSIGNALFORMAT_H +#define AVCSIGNALFORMAT_H + +#include "avc_generic.h" + +#include + +namespace AVC { + +class OutputPlugSignalFormatCmd: public AVCCommand +{ +public: + OutputPlugSignalFormatCmd(Ieee1394Service& ieee1394service); + virtual ~OutputPlugSignalFormatCmd(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual const char* getCmdName() const + { return "OutputPlugSignalFormatCmd"; } + + byte_t m_plug; + byte_t m_eoh; + byte_t m_form; + byte_t m_fmt; + byte_t m_fdf[3]; +}; + +class InputPlugSignalFormatCmd: public AVCCommand +{ +public: + InputPlugSignalFormatCmd(Ieee1394Service& ieee1394service); + virtual ~InputPlugSignalFormatCmd(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual const char* getCmdName() const + { return "InputPlugSignalFormatCmd"; } + + byte_t m_plug; + byte_t m_eoh; + byte_t m_form; + byte_t m_fmt; + byte_t m_fdf[3]; +}; + + +} + +#endif // AVCSIGNALFORMAT_H Index: trunk/libffado/src/libavc/general/avc_unit_info.cpp =================================================================== --- trunk/libffado/src/libavc/general/avc_unit_info.cpp (revision 503) +++ trunk/libffado/src/libavc/general/avc_unit_info.cpp (revision 503) @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_unit_info.h" +#include "../util/avc_serialize.h" +#include "libieee1394/ieee1394service.h" + +#include +#include + +using namespace std; + +namespace AVC { + + +UnitInfoCmd::UnitInfoCmd( Ieee1394Service& ieee1349service ) + : AVCCommand( ieee1349service, AVC1394_CMD_UNIT_INFO ) + , m_reserved( 0xff ) + , m_unit_type( 0xff ) + , m_unit( 0xff ) + , m_company_id( 0xffffffff ) +{ +} + +UnitInfoCmd::~UnitInfoCmd() +{ +} + +bool +UnitInfoCmd::serialize( IOSSerialize& se ) +{ + AVCCommand::serialize( se ); + + se.write( m_reserved, "UnitInfoCmd reserved" ); + byte_t operand = ( m_unit_type << 3 ) | ( m_unit & 0x7 ); + se.write( operand, "UnitInfoCmd unit_type and unit" ); + operand = ( m_company_id >> 16 ) & 0xff; + se.write( operand, "UnitInfoCmd company_ID (2)" ); + operand = ( m_company_id >> 8 ) & 0xff; + se.write( operand, "UnitInfoCmd company_ID (1)" ); + operand = ( m_company_id >> 0 ) & 0xff; + se.write( operand, "UnitInfoCmd company_ID (0)" ); + + return true; +} + +bool +UnitInfoCmd::deserialize( IISDeserialize& de ) +{ + AVCCommand::deserialize( de ); + + de.read( &m_reserved ); + + byte_t operand; + de.read( &operand ); + m_unit_type = ( operand >> 3 ); + m_unit = ( operand & 0x7 ); + + de.read( &operand ); + m_company_id = 0; + m_company_id |= operand << 16; + de.read( &operand ); + m_company_id |= operand << 8; + de.read( &operand ); + m_company_id |= operand; + + return true; +} + +} Index: trunk/libffado/src/libavc/general/avc_connect.h =================================================================== --- trunk/libffado/src/libavc/general/avc_connect.h (revision 503) +++ trunk/libffado/src/libavc/general/avc_connect.h (revision 503) @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVCCONNECT_H +#define AVCCONNECT_H + +#include "avc_generic.h" + +#include +namespace AVC { + +class ConnectCmd: public AVCCommand +{ +public: + ConnectCmd(Ieee1394Service& ieee1394service); + virtual ~ConnectCmd(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual const char* getCmdName() const + { return "ConnectCmd"; } +}; + +} + +#endif // AVCCONNECT_H Index: trunk/libffado/src/libavc/general/avc_subunit.h =================================================================== --- trunk/libffado/src/libavc/general/avc_subunit.h (revision 524) +++ trunk/libffado/src/libavc/general/avc_subunit.h (revision 524) @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2007 by Pieter Palmers + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVC_SUBUNIT_H +#define AVC_SUBUNIT_H + +#include "debugmodule/debugmodule.h" + +#include "../avc_definitions.h" +#include "../general/avc_plug.h" +#include "../general/avc_extended_subunit_info.h" +#include "../general/avc_generic.h" +#include "../audiosubunit/avc_function_block.h" + +#include + +#warning merge with bebob functionblock +#include "bebob/bebob_functionblock.h" + +namespace AVC { + +class Unit; + +class Subunit { + public: + Subunit( Unit& avDevice, + ESubunitType type, + subunit_t id ); + virtual ~Subunit(); + + virtual bool discover(); + virtual bool discoverConnections(); + virtual const char* getName() = 0; + + subunit_t getSubunitId() + { return m_sbId; } + ESubunitType getSubunitType() + { return m_sbType; } + + Unit& getUnit() const + { return *m_unit; } + Subunit& getSubunit() + { return *this; } + + virtual Plug *createPlug( AVC::Unit* unit, + AVC::Subunit* subunit, + AVC::function_block_type_t functionBlockType, + AVC::function_block_type_t functionBlockId, + AVC::Plug::EPlugAddressType plugAddressType, + AVC::Plug::EPlugDirection plugDirection, + AVC::plug_id_t plugId ); + + bool addPlug( Plug& plug ); + virtual bool initPlugFromDescriptor( Plug& plug ); + + PlugVector& getPlugs() + { return m_plugs; } + Plug* getPlug(Plug::EPlugDirection direction, plug_id_t plugId); + + virtual void setVerboseLevel(int l) + { setDebugLevel(l);}; + + bool serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const; + static Subunit* deserialize( Glib::ustring basePath, + Util::IODeserialize& deser, Unit& avDevice ); + protected: + Subunit(); + + virtual bool serializeChild( Glib::ustring basePath, + Util::IOSerialize& ser ) const = 0; + virtual bool deserializeChild( Glib::ustring basePath, + Util::IODeserialize& deser, + Unit& avDevice ) = 0; + bool discoverPlugs(); + bool discoverPlugs(Plug::EPlugDirection plugDirection, + AVC::plug_id_t plugMaxId ); + + protected: + Unit* m_unit; + ESubunitType m_sbType; + subunit_t m_sbId; + + PlugVector m_plugs; + + DECLARE_DEBUG_MODULE; +}; + +typedef std::vector SubunitVector; + +} + +#endif Index: trunk/libffado/src/libavc/general/avc_unit_info.h =================================================================== --- trunk/libffado/src/libavc/general/avc_unit_info.h (revision 503) +++ trunk/libffado/src/libavc/general/avc_unit_info.h (revision 503) @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef AVCUNITINFO_H +#define AVCUNITINFO_H + +#include "avc_generic.h" + +#include + +namespace AVC { + + +class UnitInfoCmd: public AVCCommand +{ +public: + + enum EUnitType { + eUT_Monitor = AVC1394_SUBUNIT_VIDEO_MONITOR, + eUT_Audio = AVC1394_SUBUNIT_AUDIO, + eUT_Printer = AVC1394_SUBUNIT_PRINTER, + eUT_Disc = AVC1394_SUBUNIT_DISC_RECORDER, + eUT_VCR = AVC1394_SUBUNIT_VCR, + eUT_Tuner = AVC1394_SUBUNIT_TUNER, + eUT_CA = AVC1394_SUBUNIT_CA, + eUT_Camera = AVC1394_SUBUNIT_VIDEO_CAMERA, + eUT_Panel = AVC1394_SUBUNIT_PANEL, + eUT_BulltinBoard = AVC1394_SUBUNIT_BULLETIN_BOARD, + eUT_CameraStorage = AVC1394_SUBUNIT_CAMERA_STORAGE, + eUT_Music = AVC1394_SUBUNIT_MUSIC, + eUT_VendorUnique = AVC1394_SUBUNIT_VENDOR_UNIQUE, + eUT_Reserved = AVC1394_SUBUNIT_RESERVED, + eUT_Extended = AVC1394_SUBUNIT_EXTENDED, + eUT_Unit = AVC1394_SUBUNIT_UNIT, + }; + + UnitInfoCmd( Ieee1394Service& ieee1349service ); + virtual ~UnitInfoCmd(); + + virtual bool serialize( IOSSerialize& se ); + virtual bool deserialize( IISDeserialize& de ); + + virtual const char* getCmdName() const + { return "UnitInfoCmd"; } + + reserved_t m_reserved; + unit_type_t m_unit_type; + unit_t m_unit; + + company_id_t m_company_id; +}; + +} + +#endif // AVCUNITINFO_H Index: trunk/libffado/src/libavc/general/avc_extended_plug_info.cpp =================================================================== --- trunk/libffado/src/libavc/general/avc_extended_plug_info.cpp (revision 505) +++ trunk/libffado/src/libavc/general/avc_extended_plug_info.cpp (revision 505) @@ -0,0 +1,860 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_extended_plug_info.h" +#include "../util/avc_serialize.h" +#include "libieee1394/ieee1394service.h" + +#include +#include + +using namespace std; + +namespace AVC { + +///////////////////////////////////////// +///////////////////////////////////////// + +ExtendedPlugInfoPlugTypeSpecificData::ExtendedPlugInfoPlugTypeSpecificData( EExtendedPlugInfoPlugType ePlugType ) + : IBusData() + , m_plugType( ePlugType ) +{ +} + +ExtendedPlugInfoPlugTypeSpecificData::~ExtendedPlugInfoPlugTypeSpecificData() +{ +} + +bool +ExtendedPlugInfoPlugTypeSpecificData::serialize( IOSSerialize& se ) +{ + se.write( m_plugType, "ExtendedPlugInfoPlugTypeSpecificData plugType" ); + return true; +} + + +bool +ExtendedPlugInfoPlugTypeSpecificData::deserialize( IISDeserialize& de ) +{ + de.read( &m_plugType ); + return true; +} + +ExtendedPlugInfoPlugTypeSpecificData* ExtendedPlugInfoPlugTypeSpecificData::clone() const +{ + return new ExtendedPlugInfoPlugTypeSpecificData( *this ); +} + +const char* extendedPlugInfoPlugTypeStrings[] = +{ + "IsoStream", + "AsyncStream", + "Midi", + "Sync", + "Analog", + "Digital", + "Unknown", +}; + +const char* extendedPlugInfoPlugTypeToString( plug_type_t plugType ) +{ + if ( plugType > sizeof( extendedPlugInfoPlugTypeStrings ) ) { + return "Unknown"; + } else { + return extendedPlugInfoPlugTypeStrings[plugType]; + } +} + +///////////////////////////////////////// +///////////////////////////////////////// + +ExtendedPlugInfoPlugNameSpecificData::ExtendedPlugInfoPlugNameSpecificData() + : IBusData() +{ +} + +ExtendedPlugInfoPlugNameSpecificData::~ExtendedPlugInfoPlugNameSpecificData() +{ +} + +bool +ExtendedPlugInfoPlugNameSpecificData::serialize( IOSSerialize& se ) +{ + byte_t length = strlen( m_name.c_str() ); + se.write( length, + "ExtendedPlugInfoPlugNameSpecificData: string length" ); + for ( unsigned int i = 0; i < length; ++i ) { + se.write( static_cast( m_name[i] ), + "ExtendedPlugInfoPlugNameSpecificData: char" ); + } + + return true; +} + +bool +ExtendedPlugInfoPlugNameSpecificData::deserialize( IISDeserialize& de ) +{ + byte_t length; + de.read( &length ); + m_name.clear(); + char* name; + de.read( &name, length ); + m_name = name; + + return true; +} + +ExtendedPlugInfoPlugNameSpecificData::ExtendedPlugInfoPlugNameSpecificData* +ExtendedPlugInfoPlugNameSpecificData::clone() const +{ + return new ExtendedPlugInfoPlugNameSpecificData( *this ); +} + + +///////////////////////////////////////// +///////////////////////////////////////// + +ExtendedPlugInfoPlugNumberOfChannelsSpecificData::ExtendedPlugInfoPlugNumberOfChannelsSpecificData() + : IBusData() + , m_nrOfChannels( 0 ) +{ +} + +ExtendedPlugInfoPlugNumberOfChannelsSpecificData::~ExtendedPlugInfoPlugNumberOfChannelsSpecificData() +{ +} + +bool +ExtendedPlugInfoPlugNumberOfChannelsSpecificData::serialize( IOSSerialize& se ) +{ + se.write( m_nrOfChannels, + "ExtendedPlugInfoPlugNumberOfChannelsSpecificData: " + "number of channels" ); + return true; +} + +bool +ExtendedPlugInfoPlugNumberOfChannelsSpecificData::deserialize( IISDeserialize& de ) +{ + de.read( &m_nrOfChannels ); + return true; +} + +ExtendedPlugInfoPlugNumberOfChannelsSpecificData::ExtendedPlugInfoPlugNumberOfChannelsSpecificData* +ExtendedPlugInfoPlugNumberOfChannelsSpecificData::clone() const +{ + return new ExtendedPlugInfoPlugNumberOfChannelsSpecificData( *this ); +} + +///////////////////////////////////////// +///////////////////////////////////////// + +ExtendedPlugInfoPlugChannelPositionSpecificData::ExtendedPlugInfoPlugChannelPositionSpecificData() + : IBusData() + , m_nrOfClusters( 0 ) +{ +} + +ExtendedPlugInfoPlugChannelPositionSpecificData::~ExtendedPlugInfoPlugChannelPositionSpecificData() +{ +} + +bool +ExtendedPlugInfoPlugChannelPositionSpecificData::serialize( IOSSerialize& se ) +{ + se.write( m_nrOfClusters, + "ExtendedPlugInfoPlugChannelPositionSpecificData: " + "number of clusters" ); + + for ( ClusterInfoVector::const_iterator it = m_clusterInfos.begin(); + it != m_clusterInfos.end(); + ++it ) + { + const ClusterInfo* clusterInfo = &( *it ); + + se.write( clusterInfo->m_nrOfChannels, + "ExtendedPlugInfoPlugChannelPositionSpecificData: " + "number of channels" ); + for ( ChannelInfoVector::const_iterator cit + = clusterInfo->m_channelInfos.begin(); + cit != clusterInfo->m_channelInfos.end(); + ++cit ) + { + const ChannelInfo* channelInfo = &( *cit ); + se.write( channelInfo->m_streamPosition, + "ExtendedPlugInfoPlugChannelPositionSpecificData: " + "stream position" ); + se.write( channelInfo->m_location, + "ExtendedPlugInfoPlugChannelPositionSpecificData: " + "location" ); + } + } + + return true; +} + +bool +ExtendedPlugInfoPlugChannelPositionSpecificData::deserialize( IISDeserialize& de ) +{ + m_clusterInfos.clear(); + + de.read( &m_nrOfClusters ); + for ( int i = 0; i < m_nrOfClusters; ++i ) { + ClusterInfo clusterInfo; + de.read ( &clusterInfo.m_nrOfChannels ); + for ( int j = 0; j < clusterInfo.m_nrOfChannels; ++j ) { + ChannelInfo channelInfo; + de.read( &channelInfo.m_streamPosition ); + de.read( &channelInfo.m_location ); + clusterInfo.m_channelInfos.push_back( channelInfo ); + } + m_clusterInfos.push_back( clusterInfo ); + } + return true; +} + +ExtendedPlugInfoPlugChannelPositionSpecificData::ExtendedPlugInfoPlugChannelPositionSpecificData* +ExtendedPlugInfoPlugChannelPositionSpecificData::clone() const +{ + return new ExtendedPlugInfoPlugChannelPositionSpecificData( *this ); +} + +///////////////////////////////////////// +///////////////////////////////////////// + +ExtendedPlugInfoPlugChannelNameSpecificData::ExtendedPlugInfoPlugChannelNameSpecificData() + : IBusData() + , m_streamPosition( 0 ) + , m_stringLength( 0xff ) +{ +} + +ExtendedPlugInfoPlugChannelNameSpecificData::~ExtendedPlugInfoPlugChannelNameSpecificData() +{ +} + +bool +ExtendedPlugInfoPlugChannelNameSpecificData::serialize( IOSSerialize& se ) +{ + se.write( m_streamPosition, + "ExtendedPlugInfoPlugChannelNameSpecificData: stream position" ); + se.write( m_stringLength, + "ExtendedPlugInfoPlugChannelNameSpecificData: string length" ); + for ( unsigned int i = 0; i < m_plugChannelName.size(); ++i ) { + se.write( static_cast( m_plugChannelName[i] ), + "ExtendedPlugInfoPlugChannelNameSpecificData: char" ); + } + + return true; +} + +bool +ExtendedPlugInfoPlugChannelNameSpecificData::deserialize( IISDeserialize& de ) +{ + de.read( &m_streamPosition ); + de.read( &m_stringLength ); + + char* name = new char[m_stringLength+1]; + for ( int i = 0; i < m_stringLength; ++i ) { + byte_t c; + de.read( &c ); + // \todo do correct encoding + if ( c == '&' ) { + c = '+'; + } + name[i] = c; + } + name[m_stringLength] = '\0'; + m_plugChannelName = name; + delete[] name; + + return true; +} + +ExtendedPlugInfoPlugChannelNameSpecificData::ExtendedPlugInfoPlugChannelNameSpecificData* +ExtendedPlugInfoPlugChannelNameSpecificData::clone() const +{ + return new ExtendedPlugInfoPlugChannelNameSpecificData( *this ); +} + +///////////////////////////////////////// +///////////////////////////////////////// +ExtendedPlugInfoPlugInputSpecificData::ExtendedPlugInfoPlugInputSpecificData() + : IBusData() +{ + UnitPlugSpecificDataPlugAddress + unitPlug( UnitPlugSpecificDataPlugAddress::ePT_PCR, 0x00 ); + m_plugAddress + = new PlugAddressSpecificData( PlugAddressSpecificData::ePD_Output, + PlugAddressSpecificData::ePAM_Unit, + unitPlug ); +} + +ExtendedPlugInfoPlugInputSpecificData::ExtendedPlugInfoPlugInputSpecificData(const ExtendedPlugInfoPlugInputSpecificData& rhs ) +{ + m_plugAddress = rhs.m_plugAddress->clone(); +} + + +ExtendedPlugInfoPlugInputSpecificData::~ExtendedPlugInfoPlugInputSpecificData() +{ + delete m_plugAddress; + m_plugAddress = 0; +} + +bool +ExtendedPlugInfoPlugInputSpecificData::serialize( IOSSerialize& se ) +{ + if ( m_plugAddress ) { + return m_plugAddress->serialize( se ); + } else { + return false; + } +} + +bool +ExtendedPlugInfoPlugInputSpecificData::deserialize( IISDeserialize& de ) +{ + return m_plugAddress->deserialize( de ); +} + +ExtendedPlugInfoPlugInputSpecificData::ExtendedPlugInfoPlugInputSpecificData* +ExtendedPlugInfoPlugInputSpecificData::clone() const +{ + return new ExtendedPlugInfoPlugInputSpecificData( *this ); +} + +///////////////////////////////////////// +///////////////////////////////////////// + +ExtendedPlugInfoPlugOutputSpecificData::ExtendedPlugInfoPlugOutputSpecificData() + : IBusData() + , m_nrOfOutputPlugs( 0 ) +{ +} + +ExtendedPlugInfoPlugOutputSpecificData::ExtendedPlugInfoPlugOutputSpecificData( const ExtendedPlugInfoPlugOutputSpecificData& rhs) + : IBusData() + , m_nrOfOutputPlugs( rhs.m_nrOfOutputPlugs ) +{ + for ( PlugAddressVector::const_iterator it = rhs.m_outputPlugAddresses.begin(); + it != rhs.m_outputPlugAddresses.end(); + ++it ) + { + m_outputPlugAddresses.push_back( ( *it )->clone() ); + } + +} + + +ExtendedPlugInfoPlugOutputSpecificData::~ExtendedPlugInfoPlugOutputSpecificData() +{ + for ( PlugAddressVector::iterator it = m_outputPlugAddresses.begin(); + it != m_outputPlugAddresses.end(); + ++it ) + { + delete *it; + } +} + +bool +ExtendedPlugInfoPlugOutputSpecificData::serialize( IOSSerialize& se ) +{ + se.write( m_nrOfOutputPlugs, "ExtendedPlugInfoPlugOutputSpecificData: number of output plugs" ); + for ( PlugAddressVector::const_iterator it = m_outputPlugAddresses.begin(); + it != m_outputPlugAddresses.end(); + ++it ) + { + ( *it )->serialize( se ); + } + + return true; +} + +bool +ExtendedPlugInfoPlugOutputSpecificData::deserialize( IISDeserialize& de ) +{ + de.read( &m_nrOfOutputPlugs ); + + for ( int i = 0; i < m_nrOfOutputPlugs; ++i ) + { + UnitPlugSpecificDataPlugAddress + unitPlug( UnitPlugSpecificDataPlugAddress::ePT_PCR, 0x00 ); + PlugAddressSpecificData* plugAddress + = new PlugAddressSpecificData( PlugAddressSpecificData::ePD_Output, + PlugAddressSpecificData::ePAM_Unit, + unitPlug ); + if ( !plugAddress->deserialize( de ) ) { + return false; + } + + m_outputPlugAddresses.push_back( plugAddress ); + } + + return true; +} + +ExtendedPlugInfoPlugOutputSpecificData::ExtendedPlugInfoPlugOutputSpecificData* +ExtendedPlugInfoPlugOutputSpecificData::clone() const +{ + return new ExtendedPlugInfoPlugOutputSpecificData( *this ); +} + +///////////////////////////////////////// +///////////////////////////////////////// +ExtendedPlugInfoClusterInfoSpecificData::ExtendedPlugInfoClusterInfoSpecificData() + : IBusData() + , m_clusterIndex( 0 ) + , m_portType( ePT_NoType ) + , m_stringLength( 0xff ) +{ +} + +ExtendedPlugInfoClusterInfoSpecificData::~ExtendedPlugInfoClusterInfoSpecificData() +{ +} + +bool +ExtendedPlugInfoClusterInfoSpecificData::serialize( IOSSerialize& se ) +{ + se.write( m_clusterIndex, + "ExtendedPlugInfoClusterInfoSpecificData: cluster index" ); + se.write( m_portType, + "ExtendedPlugInfoClusterInfoSpecificData: port type" ); + se.write( m_stringLength, + "ExtendedPlugInfoClusterInfoSpecificData: string length" ); + for ( unsigned int i = 0; i < m_clusterName.length(); ++i ) { + se.write( static_cast( m_clusterName[i] ), + "ExtendedPlugInfoClusterInfoSpecificData: char" ); + } + + return true; +} + +bool +ExtendedPlugInfoClusterInfoSpecificData::deserialize( IISDeserialize& de ) +{ + + de.read( &m_clusterIndex ); + de.read( &m_portType ); + de.read( &m_stringLength ); + + char* name = new char[m_stringLength+1]; + for ( int i = 0; i < m_stringLength; ++i ) { + byte_t c; + de.read( &c ); + // \todo do correct encoding + if ( c == '&' ) { + c = '+'; + } + name[i] = c; + } + name[m_stringLength] = '\0'; + m_clusterName = name; + delete[] name; + + return true; +} + +ExtendedPlugInfoClusterInfoSpecificData::ExtendedPlugInfoClusterInfoSpecificData* +ExtendedPlugInfoClusterInfoSpecificData::clone() const +{ + return new ExtendedPlugInfoClusterInfoSpecificData( *this ); +} + +const char* extendedPlugInfoPortTypeStrings[] = +{ + "Speaker", + "Headphone", + "Microphone", + "Line", + "SPDIF", + "ADAT", + "TDIF", + "MADI", + "Analog", + "Digital", + "MIDI", +}; + +const char* extendedPlugInfoClusterInfoPortTypeToString( port_type_t portType ) +{ + if ( portType > ( ( sizeof( extendedPlugInfoPortTypeStrings ) ) + / ( sizeof( extendedPlugInfoPortTypeStrings[0] ) ) ) ) { + return "Unknown"; + } else { + return extendedPlugInfoPortTypeStrings[portType]; + } +} + +///////////////////////////////////////// +///////////////////////////////////////// +///////////////////////////////////////// +///////////////////////////////////////// + +ExtendedPlugInfoInfoType::ExtendedPlugInfoInfoType(EInfoType eInfoType) + : IBusData() + , m_infoType( eInfoType ) + , m_plugType( 0 ) + , m_plugName( 0 ) + , m_plugNrOfChns( 0 ) + , m_plugChannelPosition( 0 ) + , m_plugChannelName( 0 ) + , m_plugInput( 0 ) + , m_plugOutput( 0 ) + , m_plugClusterInfo( 0 ) +{ +} + +ExtendedPlugInfoInfoType::ExtendedPlugInfoInfoType( const ExtendedPlugInfoInfoType& rhs ) + : IBusData() + , m_infoType( rhs.m_infoType ) + , m_plugType( 0 ) + , m_plugName( 0 ) + , m_plugNrOfChns( 0 ) + , m_plugChannelPosition( 0 ) + , m_plugChannelName( 0 ) + , m_plugInput( 0 ) + , m_plugOutput( 0 ) + , m_plugClusterInfo( 0 ) +{ + switch( m_infoType ) { + case eIT_PlugType: + m_plugType = + new ExtendedPlugInfoPlugTypeSpecificData( *rhs.m_plugType ); + break; + case eIT_PlugName: + m_plugName = + new ExtendedPlugInfoPlugNameSpecificData( *rhs.m_plugName ); + break; + case eIT_NoOfChannels: + m_plugNrOfChns = + new ExtendedPlugInfoPlugNumberOfChannelsSpecificData( *rhs.m_plugNrOfChns ); + break; + case eIT_ChannelPosition: + m_plugChannelPosition = + new ExtendedPlugInfoPlugChannelPositionSpecificData( *rhs.m_plugChannelPosition ); + break; + case eIT_ChannelName: + m_plugChannelName = + new ExtendedPlugInfoPlugChannelNameSpecificData( *rhs.m_plugChannelName ); + break; + case eIT_PlugInput: + m_plugInput = + new ExtendedPlugInfoPlugInputSpecificData( *rhs.m_plugInput ); + break; + case eIT_PlugOutput: + m_plugOutput = + new ExtendedPlugInfoPlugOutputSpecificData( *rhs.m_plugOutput ); + break; + case eIT_ClusterInfo: + m_plugClusterInfo = + new ExtendedPlugInfoClusterInfoSpecificData( *rhs.m_plugClusterInfo ); + break; + } +} + +ExtendedPlugInfoInfoType::~ExtendedPlugInfoInfoType() +{ + delete( m_plugType ); + delete( m_plugName ); + delete( m_plugNrOfChns ); + delete( m_plugChannelPosition ); + delete( m_plugChannelName ); + delete( m_plugInput ); + delete( m_plugOutput ); + delete( m_plugClusterInfo ); + } + +bool +ExtendedPlugInfoInfoType::initialize() +{ + switch ( m_infoType ) { + case eIT_PlugType: + m_plugType = new ExtendedPlugInfoPlugTypeSpecificData; + break; + case eIT_PlugName: + m_plugName = new ExtendedPlugInfoPlugNameSpecificData; + break; + case eIT_NoOfChannels: + m_plugNrOfChns = new ExtendedPlugInfoPlugNumberOfChannelsSpecificData; + break; + case eIT_ChannelPosition: + m_plugChannelPosition = new ExtendedPlugInfoPlugChannelPositionSpecificData; + break; + case eIT_ChannelName: + m_plugChannelName = new ExtendedPlugInfoPlugChannelNameSpecificData; + break; + case eIT_PlugInput: + m_plugInput = new ExtendedPlugInfoPlugInputSpecificData; + break; + case eIT_PlugOutput: + m_plugOutput = new ExtendedPlugInfoPlugOutputSpecificData; + break; + case eIT_ClusterInfo: + m_plugClusterInfo = new ExtendedPlugInfoClusterInfoSpecificData; + break; + default: + return false; + } + + return true; +} + +bool +ExtendedPlugInfoInfoType::serialize( IOSSerialize& se ) +{ + // XXX \todo improve IOSSerialize::write interface + char* buf; + asprintf( &buf, "ExtendedPlugInfoInfoType infoType (%s)", + extendedPlugInfoInfoTypeToString( m_infoType ) ); + se.write( m_infoType, buf ); + + free(buf); + + switch ( m_infoType ) { + case eIT_PlugType: + if ( m_plugType ) { + m_plugType->serialize( se ); + } + break; + case eIT_PlugName: + if ( m_plugName ) { + m_plugName->serialize( se ); + } + break; + case eIT_NoOfChannels: + if ( m_plugNrOfChns ) { + m_plugNrOfChns->serialize( se ); + } + break; + case eIT_ChannelPosition: + if ( m_plugChannelPosition ) { + m_plugChannelPosition->serialize( se ); + } + break; + case eIT_ChannelName: + if ( m_plugChannelName ) { + m_plugChannelName->serialize( se ); + } + break; + case eIT_PlugInput: + if ( m_plugInput ) { + m_plugInput->serialize( se ); + } + break; + case eIT_PlugOutput: + if ( m_plugOutput ) { + m_plugOutput->serialize( se ); + } + break; + case eIT_ClusterInfo: + if ( m_plugClusterInfo ) { + m_plugClusterInfo->serialize( se ); + } + break; + default: + return false; + } + + return true; +} + +bool +ExtendedPlugInfoInfoType::deserialize( IISDeserialize& de ) +{ + bool status = false; + + de.read( &m_infoType ); + + switch ( m_infoType ) { + case eIT_PlugType: + if ( !m_plugType ) { + m_plugType = new ExtendedPlugInfoPlugTypeSpecificData; + } + status = m_plugType->deserialize( de ); + break; + case eIT_PlugName: + if ( !m_plugName ) { + m_plugName = new ExtendedPlugInfoPlugNameSpecificData; + } + status = m_plugName->deserialize( de ); + break; + case eIT_NoOfChannels: + if ( !m_plugNrOfChns ) { + m_plugNrOfChns = + new ExtendedPlugInfoPlugNumberOfChannelsSpecificData; + } + status = m_plugNrOfChns->deserialize( de ); + break; + case eIT_ChannelPosition: + if ( !m_plugChannelPosition ) { + m_plugChannelPosition = + new ExtendedPlugInfoPlugChannelPositionSpecificData; + } + status = m_plugChannelPosition->deserialize( de ); + break; + case eIT_ChannelName: + if ( !m_plugChannelName ) { + m_plugChannelName = + new ExtendedPlugInfoPlugChannelNameSpecificData; + } + status = m_plugChannelName->deserialize( de ); + break; + case eIT_PlugInput: + if ( !m_plugInput ) { + m_plugInput = new ExtendedPlugInfoPlugInputSpecificData; + } + status = m_plugInput->deserialize( de ); + break; + case eIT_PlugOutput: + if ( !m_plugOutput ) { + m_plugOutput = new ExtendedPlugInfoPlugOutputSpecificData; + } + status = m_plugOutput->deserialize( de ); + break; + case eIT_ClusterInfo: + if ( !m_plugClusterInfo ) { + m_plugClusterInfo = new ExtendedPlugInfoClusterInfoSpecificData; + } + status =m_plugClusterInfo->deserialize( de ); + break; + default: + return false; + } + + return status; +} + +ExtendedPlugInfoInfoType* +ExtendedPlugInfoInfoType::clone() const +{ + ExtendedPlugInfoInfoType* extPlugInfoInfoType + = new ExtendedPlugInfoInfoType( *this ); + extPlugInfoInfoType->initialize(); + return extPlugInfoInfoType; +} + +const char* extendedPlugInfoInfoTypeStrings[] = +{ + "PlugType", + "PlugName", + "NoOfChannels", + "ChannelPosition", + "ChannelName", + "PlugInput", + "PlugOutput", + "ClusterInfo", +}; + +const char* extendedPlugInfoInfoTypeToString( info_type_t infoType ) +{ + if ( infoType > ( ( sizeof( extendedPlugInfoInfoTypeStrings ) ) + / ( sizeof( extendedPlugInfoInfoTypeStrings[0] ) ) ) ) { + return "Unknown"; + } else { + return extendedPlugInfoInfoTypeStrings[infoType]; + } +} + + +////////////////////////////////////////////// + +ExtendedPlugInfoCmd::ExtendedPlugInfoCmd( Ieee1394Service& ieee1394service, + ESubFunction eSubFunction ) + : AVCCommand( ieee1394service, AVC1394_CMD_PLUG_INFO ) +{ + setSubFunction( eSubFunction ); + UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, 0x00 ); + m_plugAddress = new PlugAddress( PlugAddress::ePD_Output, + PlugAddress::ePAM_Unit, + unitPlugAddress ); + m_infoType = + new ExtendedPlugInfoInfoType( ExtendedPlugInfoInfoType::eIT_PlugType ); + m_infoType->initialize(); +} + +ExtendedPlugInfoCmd::ExtendedPlugInfoCmd( const ExtendedPlugInfoCmd& rhs ) + : AVCCommand( rhs ) +{ + m_subFunction = rhs.m_subFunction; + m_plugAddress = new PlugAddress( *rhs.m_plugAddress ); + m_infoType = new ExtendedPlugInfoInfoType( *rhs.m_infoType ); +} + +ExtendedPlugInfoCmd::~ExtendedPlugInfoCmd() +{ + delete m_plugAddress; + m_plugAddress = 0; + delete m_infoType; + m_infoType = 0; +} + +bool +ExtendedPlugInfoCmd::serialize( IOSSerialize& se ) +{ + bool status = false; + AVCCommand::serialize( se ); + se.write( m_subFunction, "ExtendedPlugInfoCmd subFunction" ); + status = m_plugAddress->serialize( se ); + status &= m_infoType->serialize( se ); + + return status; +} + +bool +ExtendedPlugInfoCmd::deserialize( IISDeserialize& de ) +{ + bool status = false; + AVCCommand::deserialize( de ); + de.read( &m_subFunction ); + status = m_plugAddress->deserialize( de ); + status &= m_infoType->deserialize( de ); + + return status; +} + +bool +ExtendedPlugInfoCmd::setPlugAddress( const PlugAddress& plugAddress ) +{ + delete m_plugAddress; + m_plugAddress = plugAddress.clone(); + return true; +} + +bool +ExtendedPlugInfoCmd::setSubFunction( ESubFunction subFunction ) +{ + m_subFunction = subFunction; + return true; +} + +bool +ExtendedPlugInfoCmd::setInfoType( const ExtendedPlugInfoInfoType& infoType ) +{ + delete m_infoType; + m_infoType = infoType.clone(); + return true; +} + +} Index: trunk/libffado/src/libavc/general/avc_subunit_info.cpp =================================================================== --- trunk/libffado/src/libavc/general/avc_subunit_info.cpp (revision 505) +++ trunk/libffado/src/libavc/general/avc_subunit_info.cpp (revision 505) @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_subunit_info.h" +#include "../util/avc_serialize.h" +#include "libieee1394/ieee1394service.h" + +#include +#include + +using namespace std; + +namespace AVC { + + +SubUnitInfoCmd::SubUnitInfoCmd( Ieee1394Service& ieee1349service ) + : AVCCommand( ieee1349service, AVC1394_CMD_SUBUNIT_INFO ) +{ + clear(); +} + +bool +SubUnitInfoCmd::clear() +{ + m_page = 0xff; + m_extension_code = 0x7; + for ( int i = 0; i < eMaxSubunitsPerPage; ++i ) { + m_table[i].m_subunit_type = 0xff; + m_table[i].m_max_subunit_id = 0xff; + } + m_nrOfValidEntries = 0; + return true; +} + + +SubUnitInfoCmd::~SubUnitInfoCmd() +{ +} + +bool +SubUnitInfoCmd::serialize( IOSSerialize& se ) +{ + AVCCommand::serialize( se ); + + byte_t operand = 0; + operand = (( m_page & 0x7 ) << 4 ) | ( m_extension_code & 0x7 ); + se.write( operand, "SubUnitInfoCmd page and extension_code" ); + + for ( int i = 0; i < eMaxSubunitsPerPage; ++i ) { + operand = ( m_table[i].m_subunit_type << 3 ) + | ( m_table[i].m_max_subunit_id & 0x7 ); + se.write( operand, "SubUnitInfoCmd subunit_type and max_subunit_ID" ); + } + + return true; +} + +bool +SubUnitInfoCmd::deserialize( IISDeserialize& de ) +{ + AVCCommand::deserialize( de ); + + byte_t operand; + de.read( &operand ); + m_page = ( operand >> 4 ) & 0x7; + m_extension_code = operand & 0x7; + + m_nrOfValidEntries = 0; + for ( int i = 0; i < eMaxSubunitsPerPage; ++i ) { + de.read( &operand ); + m_table[i].m_subunit_type = operand >> 3; + m_table[i].m_max_subunit_id = operand & 0x7; + + if ( operand != 0xff ) { + m_nrOfValidEntries++; + } + } + + return true; +} + +} Index: trunk/libffado/src/libavc/util/avc_serialize.cpp =================================================================== --- trunk/libffado/src/libavc/util/avc_serialize.cpp (revision 503) +++ trunk/libffado/src/libavc/util/avc_serialize.cpp (revision 503) @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "avc_serialize.h" + +#include +#include + +#include + + +namespace AVC { + + +IMPL_DEBUG_MODULE( CoutSerializer, CoutSerializer, DEBUG_LEVEL_NORMAL ); +IMPL_DEBUG_MODULE( StringSerializer, StringSerializer, DEBUG_LEVEL_NORMAL ); +IMPL_DEBUG_MODULE( BufferSerialize, BufferSerialize, DEBUG_LEVEL_NORMAL ); +IMPL_DEBUG_MODULE( BufferDeserialize, BufferDeserialize, DEBUG_LEVEL_NORMAL ); + +bool +CoutSerializer::write( byte_t d, const char* name ) +{ + debugOutput( DEBUG_LEVEL_NORMAL, " %3d: 0x%02x %40s\n", m_cnt, d, name ); + m_cnt += sizeof( byte_t ); + + return true; +} + +bool +CoutSerializer::write( uint16_t d, const char* name ) +{ + debugOutput( DEBUG_LEVEL_NORMAL, " %3d: 0x%04x %40s\n", m_cnt, d, name ); + m_cnt += sizeof( uint16_t ); + + return true; +} + +bool +CoutSerializer::write( quadlet_t d, const char* name ) +{ + debugOutput( DEBUG_LEVEL_NORMAL, " %3d: 0x%08x %40s\n", m_cnt, d, name ); + m_cnt += sizeof( quadlet_t ); + return true; +} + +bool +CoutSerializer::write( const char * v, size_t len, const char* name ) +{ + debugOutput( DEBUG_LEVEL_NORMAL, " %3d: %s %40s\n", m_cnt, v, name ); + m_cnt += len; + return true; +} +////////////////////////////////////////////////// + +bool +StringSerializer::write( byte_t d, const char* name ) +{ + char* result; + asprintf( &result, " %3d:\t0x%02x\t%s\n", m_cnt, d, name ); + + m_string += result; + free( result ); + + m_cnt += sizeof( byte_t ); + + return true; +} + +bool +StringSerializer::write( uint16_t d, const char* name ) +{ + char* result; + asprintf( &result, " %3d:\t0x%04x\t%s\n", m_cnt, d, name ); + + m_string += result; + free( result ); + + m_cnt += sizeof( uint16_t ); + + return true; +} + +bool +StringSerializer::write( quadlet_t d, const char* name ) +{ + char* result; + asprintf( &result, " %3d:\t0x%08x\t%s\n", m_cnt, d, name ); + + m_string += result; + free( result ); + + m_cnt += sizeof( quadlet_t ); + return true; +} + +bool +StringSerializer::write( const char * v, size_t len, const char* name ) +{ + char* result; + asprintf( &result, " %3d:\t%s\t%s\n", m_cnt, v, name ); + + m_string += result; + free( result ); + + m_cnt += len; + return true; +} +////////////////////////////////////////////////// + +bool +BufferSerialize::write( byte_t value, const char* name ) +{ + bool result = false; + if ( isCurPosValid() ) { + *m_curPos = value; + m_curPos += sizeof( byte_t ); + result = true; + } + return result; +} + +bool +BufferSerialize::write( uint16_t value, const char* name ) +{ + byte_t hi = (value & 0xFF00) >> 8; + byte_t lo = value & 0xFF; + + bool result = false; + if ( isCurPosValid() ) { + *m_curPos = hi; + m_curPos += sizeof( byte_t ); + if ( isCurPosValid() ) { + *m_curPos = lo; + m_curPos += sizeof( byte_t ); + result = true; + } + } + return result; +} + +bool +BufferSerialize::write( quadlet_t value, const char* name ) +{ + bool result = false; + if ( isCurPosValid() ) { + * ( quadlet_t* )m_curPos = value; + m_curPos += sizeof( quadlet_t ); + result = true; + } + return result; +} + +bool +BufferSerialize::write( const char * v, size_t len, const char* name ) +{ + bool result = false; + if ( isCurPosValid() ) { + m_curPos += len; + // avoid write beyond buffer + if ( isCurPosValid() ) { + m_curPos -= len; + memcpy(m_curPos, v, len); + m_curPos += len; + result = true; + } + } + return result; +} + +bool +BufferSerialize::isCurPosValid() const +{ + if ( static_cast( ( m_curPos - m_buffer ) ) >= m_length ) { + return false; + } + return true; +} + +////////////////////////////////////////////////// + +bool +BufferDeserialize::read( byte_t* value ) +{ + bool result = false; + if ( isCurPosValid() ) { + *value = *m_curPos; + m_curPos += sizeof( byte_t ); + result = true; + } + return result; +} + +bool +BufferDeserialize::read( uint16_t* value ) +{ + byte_t hi; + byte_t lo; + bool result = false; + if ( isCurPosValid() ) { + hi = *((byte_t *)m_curPos); + m_curPos += sizeof( byte_t ); + if ( isCurPosValid() ) { + lo = *((byte_t *)m_curPos); + m_curPos += sizeof( byte_t ); + *value=(hi << 8) | lo; + result = true; + } + } + return result; +} + +bool +BufferDeserialize::read( quadlet_t* value ) +{ + bool result = false; + if ( isCurPosValid() ) { + *value = *( ( quadlet_t* )m_curPos ); + m_curPos += sizeof( quadlet_t ); + result = true; + } + return result; +} + +bool +BufferDeserialize::read( char** value, size_t length ) +{ + bool result = false; + if ( isCurPosValid() ) { + *value = ( char* )m_curPos; + + m_curPos += length-1; + if ( !isCurPosValid() ) { + debugError("Read past end of response\n"); + result=false; + } else { + m_curPos++; + result = true; + } + } + return result; +} + +bool +BufferDeserialize::peek( byte_t* value ) +{ + bool result = false; + if ( isCurPosValid() ) { + *value = *m_curPos; + result = true; + } + return result; +} + +bool +BufferDeserialize::peek( uint16_t* value, size_t offset ) +{ + byte_t hi; + byte_t lo; + bool result = false; + m_curPos+=offset; + if ( isCurPosValid() ) { + hi = *((byte_t *)m_curPos); + m_curPos += sizeof( byte_t ); + if ( isCurPosValid() ) { + lo = *((byte_t *)m_curPos); + *value=(hi << 8) | lo; + result = true; + } + m_curPos -= sizeof( byte_t ); + } + m_curPos-=offset; + return result; +} + +bool +BufferDeserialize::skip( size_t length ) { + m_curPos+=length; + return true; +} + +bool +BufferDeserialize::isCurPosValid() const +{ + if ( static_cast( ( m_curPos - m_buffer ) ) >= m_length ) { + return false; + } + return true; +} + +} Index: trunk/libffado/src/libavc/util/avc_serialize.h =================================================================== --- trunk/libffado/src/libavc/util/avc_serialize.h (revision 503) +++ trunk/libffado/src/libavc/util/avc_serialize.h (revision 503) @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef SERIALIZE_H +#define SERIALIZE_H + +#include "debugmodule/debugmodule.h" + +#include // byte_t and quadlet_t declaration +#include + +namespace AVC { + +// Interfaces + +class IOSSerialize { +public: + IOSSerialize() {} + virtual ~IOSSerialize() {} + + virtual bool write( byte_t value, const char* name = "" ) = 0; + virtual bool write( uint16_t value, const char* name = "" ) = 0; + virtual bool write( quadlet_t value, const char* name = "" ) = 0; + virtual bool write( const char *values, size_t len, const char* name = "" ) = 0; +}; + +class IISDeserialize { +public: + IISDeserialize() {} + virtual ~IISDeserialize() {} + + virtual bool read( byte_t* value ) = 0; + virtual bool read( uint16_t* value ) = 0; + virtual bool read( quadlet_t* value ) = 0; + virtual bool read( char** value, size_t length ) = 0; + virtual bool peek( byte_t* value ) = 0; + virtual bool peek( uint16_t* value, size_t offset )=0; + virtual bool skip( size_t length ) = 0; + virtual int getNrOfConsumedBytes() const = 0; +}; + +// Specialized implementations of previously defined interfaces + +class CoutSerializer: public IOSSerialize { +public: + CoutSerializer() + : IOSSerialize() + , m_cnt( 0 ) + {} + virtual ~CoutSerializer() {} + + virtual bool write( byte_t value, const char* name = "" ); + virtual bool write( uint16_t value, const char* name = "" ); + virtual bool write( quadlet_t value, const char* name = "" ); + virtual bool write( const char *values, size_t len, const char* name = "" ); + +private: + unsigned int m_cnt; + DECLARE_DEBUG_MODULE; + +}; + +class StringSerializer: public IOSSerialize { +public: + StringSerializer() + : IOSSerialize() + , m_cnt( 0 ) + {} + virtual ~StringSerializer() {} + + virtual bool write( byte_t value, const char* name = "" ); + virtual bool write( uint16_t value, const char* name = "" ); + virtual bool write( quadlet_t value, const char* name = "" ); + virtual bool write( const char *values, size_t len, const char* name = "" ); + virtual std::string getString( ) { return m_string;}; + +private: + unsigned int m_cnt; + std::string m_string; + DECLARE_DEBUG_MODULE; +}; + +class BufferSerialize: public IOSSerialize { +public: + BufferSerialize( unsigned char* buffer, size_t length ) + : IOSSerialize() + , m_buffer( buffer ) + , m_curPos( m_buffer ) + , m_length( length ) + {} + virtual ~BufferSerialize() {} + + virtual bool write( byte_t value, const char* name = "" ); + virtual bool write( uint16_t value, const char* name = "" ); + virtual bool write( quadlet_t value, const char* name = "" ); + virtual bool write( const char *values, size_t len, const char* name = "" ); + + int getNrOfProducesBytes() const + { return m_curPos - m_buffer; } + +protected: + inline bool isCurPosValid() const; + +private: + unsigned char* m_buffer; + unsigned char* m_curPos; + size_t m_length; + DECLARE_DEBUG_MODULE; +}; + +class BufferDeserialize: public IISDeserialize { +public: + BufferDeserialize( const unsigned char* buffer, size_t length ) + : IISDeserialize() + , m_buffer( const_cast( buffer ) ) + , m_curPos( m_buffer ) + , m_length( length ) + {} + virtual ~BufferDeserialize() {} + + virtual bool read( byte_t* value ); + virtual bool read( uint16_t* value ); + virtual bool read( quadlet_t* value ); + virtual bool read( char** value, size_t length ); + virtual bool peek( byte_t* value ); + virtual bool peek( uint16_t* value, size_t offset ); + virtual bool skip( size_t length ); + + int getNrOfConsumedBytes() const + { return m_curPos - m_buffer; } + +protected: + inline bool isCurPosValid() const; + +private: + unsigned char* m_buffer; // start of the buffer + unsigned char* m_curPos; // current read pos + size_t m_length; // size of buffer + DECLARE_DEBUG_MODULE; +}; + +} +#endif // SERIALIZE_H + Index: trunk/libffado/src/libavc/avc_extended_plug_info.h =================================================================== --- trunk/libffado/src/libavc/avc_extended_plug_info.h (revision 445) +++ (revision ) @@ -1,318 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#ifndef AVCEXTENDEDPLUGINFO_H -#define AVCEXTENDEDPLUGINFO_H - -#include "avc_extended_cmd_generic.h" -#include "avc_generic.h" - -#include - -#include -#include - -class ExtendedPlugInfoPlugTypeSpecificData : public IBusData -{ -public: - enum EExtendedPlugInfoPlugType { - eEPIPT_IsoStream = 0x0, - eEPIPT_AsyncStream = 0x1, - eEPIPT_Midi = 0x2, - eEPIPT_Sync = 0x3, - eEPIPT_Analog = 0x4, - eEPIPT_Digital = 0x5, - - eEPIPT_Unknown = 0xff, - }; - - ExtendedPlugInfoPlugTypeSpecificData( EExtendedPlugInfoPlugType ePlugType = eEPIPT_Unknown); - virtual ~ExtendedPlugInfoPlugTypeSpecificData(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual ExtendedPlugInfoPlugTypeSpecificData* clone() const; - - typedef byte_t plug_type_t; - - plug_type_t m_plugType; -}; - -const char* extendedPlugInfoPlugTypeToString( plug_type_t plugType ); - -///////////////////////////////////////// - -class ExtendedPlugInfoPlugNameSpecificData : public IBusData -{ -public: - ExtendedPlugInfoPlugNameSpecificData(); - virtual ~ExtendedPlugInfoPlugNameSpecificData(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual ExtendedPlugInfoPlugNameSpecificData* clone() const; - - std::string m_name; -}; - -///////////////////////////////////////// - -class ExtendedPlugInfoPlugNumberOfChannelsSpecificData : public IBusData -{ -public: - ExtendedPlugInfoPlugNumberOfChannelsSpecificData(); - virtual ~ExtendedPlugInfoPlugNumberOfChannelsSpecificData(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual ExtendedPlugInfoPlugNumberOfChannelsSpecificData* clone() const; - - nr_of_channels_t m_nrOfChannels; -}; - - -///////////////////////////////////////// - -class ExtendedPlugInfoPlugChannelPositionSpecificData : public IBusData -{ -public: - enum ELocation { - eEPI_LeftFront = 0x01, - eEPI_RightFront = 0x02, - eEPI_Center = 0x03, - eEPI_Subwoofer = 0x04, - eEPI_LeftSurround = 0x05, - eEPI_RightSurround = 0x06, - eEPI_LeftOfCenter = 0x07, - eEPI_RightOfCenter = 0x08, - eEPI_Surround = 0x09, - eEPI_SideLeft = 0x0a, - eEPI_SideRight = 0x0b, - eEPI_Top = 0x0c, - eEPI_Bottom = 0x0d, - eEPI_LeftFrontEffect = 0x0e, - eEPI_RightFrontEffect = 0x0f, - eEPI_NoPostion = 0xff, - }; - - struct ChannelInfo { - stream_position_t m_streamPosition; - stream_position_location_t m_location; - }; - - typedef std::vector ChannelInfoVector; - - struct ClusterInfo { - nr_of_channels_t m_nrOfChannels; - ChannelInfoVector m_channelInfos; - }; - - ExtendedPlugInfoPlugChannelPositionSpecificData(); - virtual ~ExtendedPlugInfoPlugChannelPositionSpecificData(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual ExtendedPlugInfoPlugChannelPositionSpecificData* clone() const; - - typedef std::vector ClusterInfoVector; - - nr_of_clusters_t m_nrOfClusters; - ClusterInfoVector m_clusterInfos; -}; - -///////////////////////////////////////// - -class ExtendedPlugInfoPlugChannelNameSpecificData : public IBusData -{ -public: - ExtendedPlugInfoPlugChannelNameSpecificData(); - virtual ~ExtendedPlugInfoPlugChannelNameSpecificData(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual ExtendedPlugInfoPlugChannelNameSpecificData* clone() const; - - stream_position_t m_streamPosition; - string_length_t m_stringLength; - std::string m_plugChannelName; -}; - -///////////////////////////////////////// - -class ExtendedPlugInfoPlugInputSpecificData : public IBusData -{ -public: - ExtendedPlugInfoPlugInputSpecificData(); - ExtendedPlugInfoPlugInputSpecificData( const ExtendedPlugInfoPlugInputSpecificData& rhs ); - virtual ~ExtendedPlugInfoPlugInputSpecificData(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual ExtendedPlugInfoPlugInputSpecificData* clone() const; - - PlugAddressSpecificData* m_plugAddress; -}; - - -///////////////////////////////////////// - -class ExtendedPlugInfoPlugOutputSpecificData : public IBusData -{ -public: - ExtendedPlugInfoPlugOutputSpecificData(); - ExtendedPlugInfoPlugOutputSpecificData( const ExtendedPlugInfoPlugOutputSpecificData& rhs ); - virtual ~ExtendedPlugInfoPlugOutputSpecificData(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual ExtendedPlugInfoPlugOutputSpecificData* clone() const; - - number_of_output_plugs_t m_nrOfOutputPlugs; - - typedef std::vector PlugAddressVector; - PlugAddressVector m_outputPlugAddresses; -}; - -///////////////////////////////////////// - -class ExtendedPlugInfoClusterInfoSpecificData : public IBusData -{ -public: - enum EPortType { - ePT_Speaker = 0x00, - ePT_Headphone = 0x01, - ePT_Microphone = 0x02, - ePT_Line = 0x03, - ePT_SPDIF = 0x04, - ePT_ADAT = 0x05, - ePT_TDIF = 0x06, - ePT_MADI = 0x07, - ePT_Analog = 0x08, - ePT_Digital = 0x09, - ePT_MIDI = 0x0a, - ePT_NoType = 0xff, - }; - - ExtendedPlugInfoClusterInfoSpecificData(); - virtual ~ExtendedPlugInfoClusterInfoSpecificData(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual ExtendedPlugInfoClusterInfoSpecificData* clone() const; - - cluster_index_t m_clusterIndex; - port_type_t m_portType; - string_length_t m_stringLength; - std::string m_clusterName; -}; - -const char* extendedPlugInfoClusterInfoPortTypeToString( port_type_t portType ); - -///////////////////////////////////////// - -#define AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_TYPE 0x00 -#define AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_NAME 0x01 -#define AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_NO_OF_CHANNELS 0x02 -#define AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_CHANNEL_POSITION 0x03 -#define AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_CHANNEL_NAME 0x04 -#define AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_INPUT 0x05 -#define AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_OUTPUT 0x06 -#define AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_CLUSTER_INFO 0x07 - -class ExtendedPlugInfoInfoType : public IBusData -{ -public: - enum EInfoType { - eIT_PlugType = AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_TYPE, - eIT_PlugName = AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_NAME, - eIT_NoOfChannels = AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_NO_OF_CHANNELS, - eIT_ChannelPosition = AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_CHANNEL_POSITION, - eIT_ChannelName = AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_CHANNEL_NAME, - eIT_PlugInput = AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_INPUT, - eIT_PlugOutput = AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_OUTPUT, - eIT_ClusterInfo = AVC1394_EXTENDED_PLUG_INFO_INFO_TYPE_PLUG_CLUSTER_INFO, - }; - - ExtendedPlugInfoInfoType(EInfoType eInfoType); - ExtendedPlugInfoInfoType( const ExtendedPlugInfoInfoType& rhs ); - virtual ~ExtendedPlugInfoInfoType(); - - bool initialize(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual ExtendedPlugInfoInfoType* clone() const; - - info_type_t m_infoType; - - ExtendedPlugInfoPlugTypeSpecificData* m_plugType; - ExtendedPlugInfoPlugNameSpecificData* m_plugName; - ExtendedPlugInfoPlugNumberOfChannelsSpecificData* m_plugNrOfChns; - ExtendedPlugInfoPlugChannelPositionSpecificData* m_plugChannelPosition; - ExtendedPlugInfoPlugChannelNameSpecificData* m_plugChannelName; - ExtendedPlugInfoPlugInputSpecificData* m_plugInput; - ExtendedPlugInfoPlugOutputSpecificData* m_plugOutput; - ExtendedPlugInfoClusterInfoSpecificData* m_plugClusterInfo; -}; - -const char* extendedPlugInfoInfoTypeToString( info_type_t infoType ); - -///////////////////////////////////////////////////////// - -#define AVC1394_PLUG_INFO_SUBFUNCTION_EXTENDED_PLUG_INFO_CMD 0xC0 -#define AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_NOT_USED 0xFF - - -class ExtendedPlugInfoCmd: public AVCCommand -{ -public: - enum ESubFunction { - eSF_ExtendedPlugInfoCmd = AVC1394_PLUG_INFO_SUBFUNCTION_EXTENDED_PLUG_INFO_CMD, - eSF_NotUsed = AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_NOT_USED, - }; - - ExtendedPlugInfoCmd( Ieee1394Service& ieee1394service, - ESubFunction eSubFunction = eSF_ExtendedPlugInfoCmd ); - ExtendedPlugInfoCmd( const ExtendedPlugInfoCmd& rhs ); - virtual ~ExtendedPlugInfoCmd(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - - bool setPlugAddress( const PlugAddress& plugAddress ); - bool setSubFunction( ESubFunction subFunction ); - bool setInfoType( const ExtendedPlugInfoInfoType& infoType ); - ExtendedPlugInfoInfoType* getInfoType() - { return m_infoType; } - - virtual const char* getCmdName() const - { return "ExtendedPlugInfoCmd"; } - -protected: - subfunction_t m_subFunction; - PlugAddress* m_plugAddress; - ExtendedPlugInfoInfoType* m_infoType; -}; - - -#endif Index: trunk/libffado/src/libavc/avc_subunit_info.h =================================================================== --- trunk/libffado/src/libavc/avc_subunit_info.h (revision 445) +++ (revision ) @@ -1,76 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#ifndef AVCSUBUNITINFO_H -#define AVCSUBUNITINFO_H - -#include "avc_generic.h" - -#include - - -// No extended subunit queries supported - -class SubUnitInfoCmd: public AVCCommand -{ -public: - SubUnitInfoCmd( Ieee1394Service& ieee1349service ); - virtual ~SubUnitInfoCmd(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - - virtual const char* getCmdName() const - { return "SubUnitInfoCmd"; } - - bool clear(); - - page_t m_page; - extension_code_t m_extension_code; - - - - enum { - eMaxSubunitsPerPage = 4, - eMaxSubunitsPerUnit = 32, - }; - - struct TableEntry { - subunit_type_t m_subunit_type; - max_subunit_id_t m_max_subunit_id; - }; - - struct TableEntry m_table[eMaxSubunitsPerPage]; - - short getMaxNoOfPages() - { return eMaxSubunitsPerUnit / eMaxSubunitsPerPage; } - - - short m_nrOfValidEntries; - short getNrOfValidEntries() - { return m_nrOfValidEntries; } - -}; - - -#endif // AVCSUBUNITINFO_H Index: trunk/libffado/src/libavc/avc_generic.cpp =================================================================== --- trunk/libffado/src/libavc/avc_generic.cpp (revision 445) +++ (revision ) @@ -1,309 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "avc_generic.h" -#include "avc_serialize.h" -#include "libieee1394/ieee1394service.h" - -#include "debugmodule/debugmodule.h" - -#include - -#define DEBUG_EXTRA_VERBOSE 5 - -IMPL_DEBUG_MODULE( AVCCommand, AVCCommand, DEBUG_LEVEL_NORMAL ); -IMPL_DEBUG_MODULE( IBusData, IBusData, DEBUG_LEVEL_VERBOSE ); - -int AVCCommand::m_time = 0; - -AVCCommand::AVCCommand( Ieee1394Service& ieee1394service, - opcode_t opcode ) - : m_p1394Service( &ieee1394service ) - , m_nodeId( 0 ) - , m_ctype( eCT_Unknown ) - , m_subunit( 0xff ) - , m_opcode( opcode ) - , m_eResponse( eR_Unknown ) -{ - -} - -bool -AVCCommand::serialize( IOSSerialize& se ) -{ - // XXX \todo improve IOSSerialize::write interface - char* buf; - asprintf( &buf, "AVCCommand ctype ('%s')", - responseToString( static_cast( m_ctype ) ) ); - se.write( m_ctype, buf ); - free( buf ); - - asprintf( &buf, "AVCCommand subunit (subunit_type = %d, subunit_id = %d)", - getSubunitType(), getSubunitId() ); - se.write( m_subunit, buf ); - free( buf ); - - se.write( m_opcode, "AVCCommand opcode" ); - return true; -} - -bool -AVCCommand::deserialize( IISDeserialize& de ) -{ - de.read( &m_ctype ); - de.read( &m_subunit ); - de.read( &m_opcode ); - return true; -} - -bool -AVCCommand::setCommandType( ECommandType commandType ) -{ - m_ctype = commandType; - m_commandType = commandType; - return true; -} - -AVCCommand::ECommandType -AVCCommand::getCommandType() -{ - return m_commandType; -} - -AVCCommand::EResponse -AVCCommand::getResponse() -{ - return m_eResponse; -} - -bool -AVCCommand::setSubunitType(ESubunitType subunitType) -{ - byte_t subT = subunitType; - - m_subunit = ( subT << 3 ) | ( m_subunit & 0x7 ); - return true; -} - -bool -AVCCommand::setNodeId( fb_nodeid_t nodeId ) -{ - m_nodeId = nodeId; - return true; -} - -bool -AVCCommand::setSubunitId(subunit_id_t subunitId) -{ - m_subunit = ( subunitId & 0x7 ) | ( m_subunit & 0xf8 ); - return true; -} - -AVCCommand::ESubunitType -AVCCommand::getSubunitType() -{ - return static_cast( ( m_subunit >> 3 ) ); -} - -subunit_id_t -AVCCommand::getSubunitId() -{ - return m_subunit & 0x7; -} - -bool -AVCCommand::setVerbose( int verboseLevel ) -{ - setDebugLevel(verboseLevel); - return true; -} - -int -AVCCommand::getVerboseLevel() -{ - return getDebugLevel(); -} - - -void -AVCCommand::showFcpFrame( const unsigned char* buf, - unsigned short frameSize ) const -{ - for ( int i = 0; i < frameSize; ++i ) { - if ( ( i % 16 ) == 0 ) { - if ( i > 0 ) { - debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "\n" ); - } - debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, " %3d:\t", i ); - } else if ( ( i % 4 ) == 0 ) { - debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, " " ); - } - debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "%02x ", buf[i] ); - } - debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "\n" ); -} - -bool -AVCCommand::fire() -{ - memset( &m_fcpFrame, 0x0, sizeof( m_fcpFrame ) ); - - BufferSerialize se( m_fcpFrame, sizeof( m_fcpFrame ) ); - if ( !serialize( se ) ) { - debugFatal( "ExtendedPlugInfoCmd::fire: Could not serialize\n" ); - return false; - } - - unsigned short fcpFrameSize = se.getNrOfProducesBytes(); - - if (getDebugLevel() >= DEBUG_LEVEL_VERY_VERBOSE) { - debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE, "%s:\n", getCmdName() ); - debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE, " Request:\n"); - showFcpFrame( m_fcpFrame, fcpFrameSize ); - - StringSerializer se_dbg; - serialize( se_dbg ); - - debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "%s\n", - se_dbg.getString().c_str()); - } - - unsigned int resp_len; - quadlet_t* resp = m_p1394Service->transactionBlock( m_nodeId, - (quadlet_t*)m_fcpFrame, - ( fcpFrameSize+3 ) / 4, - &resp_len ); - bool result = false; - if ( resp ) { - resp_len *= 4; - unsigned char* buf = ( unsigned char* ) resp; - - m_eResponse = ( EResponse )( *buf ); - switch ( m_eResponse ) - { - case eR_Accepted: - case eR_Implemented: - case eR_Rejected: - case eR_NotImplemented: - { - BufferDeserialize de( buf, resp_len ); - result = deserialize( de ); - - debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE," Response:\n"); - showFcpFrame( buf, de.getNrOfConsumedBytes() ); - - StringSerializer se_dbg; - serialize( se_dbg ); - - debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "%s\n", - se_dbg.getString().c_str()); - } - break; - default: - debugWarning( "unexpected response received (0x%x)\n", m_eResponse ); - debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE," Response:\n"); - - BufferDeserialize de( buf, resp_len ); - deserialize( de ); - - showFcpFrame( buf, de.getNrOfConsumedBytes() ); - - } - } else { - debugWarning( "no response\n" ); - } - - debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE, "\n" ); - - m_p1394Service->transactionBlockClose(); - - usleep( m_time ); - - return result; -} - -void -AVCCommand::setSleepAfterAVCCommand( int time ) -{ - m_time = time; -} - -const char* subunitTypeStrings[] = -{ - "Monitor", - "Audio", - "Printer", - "Disc recorder", - "Tape recorder/VCR", - "Tuner", - "CA", - "Video camera", - "unknown", - "Panel", - "Bulletin board", - "Camera storage", - "Music", -}; - -const char* -subunitTypeToString( subunit_type_t subunitType ) -{ - if ( subunitType == AVCCommand::eST_Unit ) { - return "Unit"; - } - if ( subunitType > ( int ) ( sizeof( subunitTypeStrings ) - / sizeof( subunitTypeStrings[0] ) ) ) { - return "unknown"; - } else { - return subunitTypeStrings[subunitType]; - } -} - -const char* responseToStrings[] = -{ - "control", - "status", - "specific inquiry", - "notify", - "general inquiry", - "reserved for future specification", - "reserved for future specification", - "reserved for future specification", - "not implemented", - "accepted", - "rejected", - "in transition", - "implemented/stable", - "changed" - "reserved for future specification", - "interim", -}; - -const char* -responseToString( AVCCommand::EResponse eResponse ) -{ - if ( eResponse > ( int )( sizeof( responseToStrings ) / sizeof( responseToStrings[0] ) ) ) { - return "unknown"; - } - return responseToStrings[eResponse]; -} Index: trunk/libffado/src/libavc/avc_extended_cmd_generic.cpp =================================================================== --- trunk/libffado/src/libavc/avc_extended_cmd_generic.cpp (revision 445) +++ (revision ) @@ -1,559 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "avc_extended_cmd_generic.h" -#include "avc_serialize.h" -#include "libieee1394/ieee1394service.h" - -UnitPlugAddress::UnitPlugAddress( EPlugType plugType, plug_type_t plugId ) - : m_plugType( plugType ) - , m_plugId( plugId ) - , m_reserved( 0xff ) -{ -} - -UnitPlugAddress::~UnitPlugAddress() -{ -} - -bool -UnitPlugAddress::serialize( IOSSerialize& se ) -{ - se.write( m_plugType, "UnitPlugAddress plugType" ); - se.write( m_plugId, "UnitPlugAddress plugId" ); - se.write( m_reserved, "UnitPlugAddress reserved" ); - return true; -} - -bool -UnitPlugAddress::deserialize( IISDeserialize& de ) -{ - de.read( &m_plugType ); - de.read( &m_plugId ); - de.read( &m_reserved ); - return true; -} - -UnitPlugAddress* -UnitPlugAddress::clone() const -{ - return new UnitPlugAddress( *this ); -} - -//////////////////////////////////////////////////////////// - -SubunitPlugAddress::SubunitPlugAddress( plug_id_t plugId ) - : m_plugId( plugId ) - , m_reserved0( 0xff ) - , m_reserved1( 0xff ) -{ -} - -SubunitPlugAddress::~SubunitPlugAddress() -{ -} - -bool -SubunitPlugAddress::serialize( IOSSerialize& se ) -{ - se.write( m_plugId, "SubunitPlugAddress plugId" ); - se.write( m_reserved0, "SubunitPlugAddress reserved0" ); - se.write( m_reserved1, "SubunitPlugAddress reserved1" ); - return true; -} - -bool -SubunitPlugAddress::deserialize( IISDeserialize& de ) -{ - de.read( &m_plugId ); - de.read( &m_reserved0 ); - de.read( &m_reserved1 ); - return true; -} - -SubunitPlugAddress* -SubunitPlugAddress::clone() const -{ - return new SubunitPlugAddress( *this ); -} - -//////////////////////////////////////////////////////////// - -FunctionBlockPlugAddress::FunctionBlockPlugAddress( function_block_type_t functionBlockType, - function_block_id_t functionBlockId, - plug_id_t plugId ) - : m_functionBlockType( functionBlockType ) - , m_functionBlockId( functionBlockId ) - , m_plugId( plugId ) -{ -} - -FunctionBlockPlugAddress::~FunctionBlockPlugAddress() -{ -} - -bool -FunctionBlockPlugAddress::serialize( IOSSerialize& se ) -{ - se.write( m_functionBlockType, "FunctionBlockPlugAddress functionBlockType" ); - se.write( m_functionBlockId, "FunctionBlockPlugAddress functionBlockId" ); - se.write( m_plugId, "FunctionBlockPlugAddress plugId" ); - return true; -} - -bool -FunctionBlockPlugAddress::deserialize( IISDeserialize& de ) -{ - de.read( &m_functionBlockType ); - de.read( &m_functionBlockId ); - de.read( &m_plugId ); - return true; -} - -FunctionBlockPlugAddress* -FunctionBlockPlugAddress:: clone() const -{ - return new FunctionBlockPlugAddress( *this ); -} - -//////////////////////////////////////////////////////////// - -UndefinedPlugAddress::UndefinedPlugAddress() - : m_reserved0( 0xff ) - , m_reserved1( 0xff ) - , m_reserved2( 0xff ) -{ -} - -UndefinedPlugAddress::~UndefinedPlugAddress() -{ -} - -bool -UndefinedPlugAddress::serialize( IOSSerialize& se ) -{ - se.write( m_reserved0, "UndefinedPlugAddress reserved0" ); - se.write( m_reserved1, "UndefinedPlugAddress reserved1" ); - se.write( m_reserved2, "UndefinedPlugAddress reserved2" ); - return true; -} - -bool -UndefinedPlugAddress::deserialize( IISDeserialize& de ) -{ - de.read( &m_reserved0 ); - de.read( &m_reserved1 ); - de.read( &m_reserved2 ); - return true; -} - -UndefinedPlugAddress* -UndefinedPlugAddress:: clone() const -{ - return new UndefinedPlugAddress( *this ); -} - -//////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////// - -UnitPlugSpecificDataPlugAddress::UnitPlugSpecificDataPlugAddress( EPlugType plugType, plug_type_t plugId ) - : m_plugType( plugType ) - , m_plugId( plugId ) - , m_reserved0( 0xff ) - , m_reserved1( 0xff ) - , m_reserved2( 0xff ) -{ -} - -UnitPlugSpecificDataPlugAddress::~UnitPlugSpecificDataPlugAddress() -{ -} - -bool -UnitPlugSpecificDataPlugAddress::serialize( IOSSerialize& se ) -{ - se.write( m_plugType, "UnitPlugSpecificDataPlugAddress plugType" ); - se.write( m_plugId, "UnitPlugSpecificDataPlugAddress plugId" ); - se.write( m_reserved0, "UnitPlugSpecificDataPlugAddress reserved0" ); - se.write( m_reserved1, "UnitPlugSpecificDataPlugAddress reserved1" ); - se.write( m_reserved2, "UnitPlugSpecificDataPlugAddress reserved2" ); - return true; -} - -bool -UnitPlugSpecificDataPlugAddress::deserialize( IISDeserialize& de ) -{ - de.read( &m_plugType ); - de.read( &m_plugId ); - de.read( &m_reserved0 ); - de.read( &m_reserved1 ); - de.read( &m_reserved2 ); - return true; -} - -UnitPlugSpecificDataPlugAddress* -UnitPlugSpecificDataPlugAddress::clone() const -{ - return new UnitPlugSpecificDataPlugAddress( *this ); -} - -//////////////////////////////////////////////////////////// - -SubunitPlugSpecificDataPlugAddress::SubunitPlugSpecificDataPlugAddress( - AVCCommand::ESubunitType subunitType, - subunit_id_t subunitId, - plug_id_t plugId ) - : m_subunitType( subunitType ) - , m_subunitId( subunitId ) - , m_plugId( plugId ) - , m_reserved0( 0xff ) - , m_reserved1( 0xff ) -{ -} - -SubunitPlugSpecificDataPlugAddress::~SubunitPlugSpecificDataPlugAddress() -{ -} - -bool -SubunitPlugSpecificDataPlugAddress::serialize( IOSSerialize& se ) -{ - se.write( m_subunitType, "SubunitPlugSpecificDataPlugAddress subunitType" ); - se.write( m_subunitId, "SubunitPlugSpecificDataPlugAddress subunitId" ); - se.write( m_plugId, "SubunitPlugSpecificDataPlugAddress plugId" ); - se.write( m_reserved0, "SubunitPlugSpecificDataPlugAddress reserved0" ); - se.write( m_reserved1, "SubunitPlugSpecificDataPlugAddress reserved1" ); - return true; -} - -bool -SubunitPlugSpecificDataPlugAddress::deserialize( IISDeserialize& de ) -{ - de.read( &m_subunitType ); - de.read( &m_subunitId ); - de.read( &m_plugId ); - de.read( &m_reserved0 ); - de.read( &m_reserved1 ); - return true; -} - -SubunitPlugSpecificDataPlugAddress* -SubunitPlugSpecificDataPlugAddress::clone() const -{ - return new SubunitPlugSpecificDataPlugAddress( *this ); -} - -//////////////////////////////////////////////////////////// - -FunctionBlockPlugSpecificDataPlugAddress::FunctionBlockPlugSpecificDataPlugAddress( - AVCCommand::ESubunitType subunitType, - subunit_id_t subunitId, - function_block_type_t functionBlockType, - function_block_id_t functionBlockId, - plug_id_t plugId ) - : m_subunitType( subunitType ) - , m_subunitId( subunitId ) - , m_functionBlockType( functionBlockType ) - , m_functionBlockId( functionBlockId ) - , m_plugId( plugId ) -{ -} - -FunctionBlockPlugSpecificDataPlugAddress::~FunctionBlockPlugSpecificDataPlugAddress() -{ -} - -bool -FunctionBlockPlugSpecificDataPlugAddress::serialize( IOSSerialize& se ) -{ - se.write( m_subunitType, "FunctionPlugSpecificDataBlockPlugAddress subunitType" ); - se.write( m_subunitId, "FunctionPlugSpecificDataBlockPlugAddress subunitId" ); - se.write( m_functionBlockType, "FunctionBlockPlugSpecificDataPlugAddress functionBlockType" ); - se.write( m_functionBlockId, "FunctionBlockPlugSpecificDataPlugAddress functionBlockId" ); - se.write( m_plugId, "FunctionBlockPlugSpecificDataPlugAddress plugId" ); - return true; -} - -bool -FunctionBlockPlugSpecificDataPlugAddress::deserialize( IISDeserialize& de ) -{ - de.read( &m_subunitType ); - de.read( &m_subunitId ); - de.read( &m_functionBlockType ); - de.read( &m_functionBlockId ); - de.read( &m_plugId ); - return true; -} - -FunctionBlockPlugSpecificDataPlugAddress* -FunctionBlockPlugSpecificDataPlugAddress:: clone() const -{ - return new FunctionBlockPlugSpecificDataPlugAddress( *this ); -} - -//////////////////////////////////////////////////////////// - -UndefinedPlugSpecificDataPlugAddress::UndefinedPlugSpecificDataPlugAddress() - : m_reserved0( 0xff ) - , m_reserved1( 0xff ) - , m_reserved2( 0xff ) - , m_reserved3( 0xff ) - , m_reserved4( 0xff ) -{ -} - -UndefinedPlugSpecificDataPlugAddress::~UndefinedPlugSpecificDataPlugAddress() -{ -} - -bool -UndefinedPlugSpecificDataPlugAddress::serialize( IOSSerialize& se ) -{ - se.write( m_reserved0, "UndefinedPlugAddress reserved0" ); - se.write( m_reserved1, "UndefinedPlugAddress reserved1" ); - se.write( m_reserved2, "UndefinedPlugAddress reserved2" ); - se.write( m_reserved3, "UndefinedPlugAddress reserved3" ); - se.write( m_reserved4, "UndefinedPlugAddress reserved4" ); - return true; -} - -bool -UndefinedPlugSpecificDataPlugAddress::deserialize( IISDeserialize& de ) -{ - de.read( &m_reserved0 ); - de.read( &m_reserved1 ); - de.read( &m_reserved2 ); - de.read( &m_reserved3 ); - de.read( &m_reserved4 ); - return true; -} - -UndefinedPlugSpecificDataPlugAddress* -UndefinedPlugSpecificDataPlugAddress:: clone() const -{ - return new UndefinedPlugSpecificDataPlugAddress( *this ); -} - -//////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////// - -PlugAddress::PlugAddress( EPlugDirection plugDirection, - EPlugAddressMode plugAddressMode, - UnitPlugAddress& unitPlugAddress ) - : m_plugDirection( plugDirection ) - , m_addressMode( plugAddressMode ) - , m_plugAddressData( new UnitPlugAddress( unitPlugAddress ) ) -{ -} - -PlugAddress::PlugAddress( EPlugDirection plugDirection, - EPlugAddressMode plugAddressMode, - SubunitPlugAddress& subUnitPlugAddress ) - : m_plugDirection( plugDirection ) - , m_addressMode( plugAddressMode ) - , m_plugAddressData( new SubunitPlugAddress( subUnitPlugAddress ) ) -{ -} - -PlugAddress::PlugAddress( EPlugDirection plugDirection, - EPlugAddressMode plugAddressMode, - FunctionBlockPlugAddress& functionBlockPlugAddress ) - : m_plugDirection( plugDirection ) - , m_addressMode( plugAddressMode ) - , m_plugAddressData( new FunctionBlockPlugAddress( functionBlockPlugAddress ) ) -{ -} - -PlugAddress::PlugAddress() - : m_plugDirection( ePD_Undefined ) - , m_addressMode( ePAM_Undefined ) - , m_plugAddressData( new UndefinedPlugAddress() ) -{ -} - -PlugAddress::PlugAddress( const PlugAddress& pa ) - : m_plugDirection( pa.m_plugDirection ) - , m_addressMode( pa.m_addressMode ) - , m_plugAddressData( dynamic_cast( pa.m_plugAddressData->clone() ) ) -{ -} - -PlugAddress::~PlugAddress() -{ - delete m_plugAddressData; - m_plugAddressData = 0; -} - -bool -PlugAddress::serialize( IOSSerialize& se ) -{ - se.write( m_plugDirection, "PlugAddress plugDirection" ); - se.write( m_addressMode, "PlugAddress addressMode" ); - return m_plugAddressData->serialize( se ); -} - -bool -PlugAddress::deserialize( IISDeserialize& de ) -{ - de.read( &m_plugDirection ); - de.read( &m_addressMode ); - return m_plugAddressData->deserialize( de ); -} - -PlugAddress* -PlugAddress::clone() const -{ - return new PlugAddress( *this ); -} - -const char* plugAddressDirectionStrings[] = -{ - "Input", - "Output", - "Undefined", -}; - -const char* plugAddressAddressModeStrings[] = -{ - "Unit", - "Subunit", - "FunctionBlock", - "Undefined", -}; - -const char* -plugAddressPlugDirectionToString( PlugAddress::EPlugDirection direction ) -{ - if ( direction > PlugAddress::ePD_Output ) { - direction = PlugAddress::ePD_Undefined; - } - return plugAddressDirectionStrings[direction]; -} - -const char* -plugAddressAddressModeToString( PlugAddress::EPlugAddressMode mode ) -{ - if ( mode > PlugAddress::ePAM_FunctionBlock ) { - mode = PlugAddress::ePAM_FunctionBlock; - } - return plugAddressAddressModeStrings[mode]; -} - - -//////////////////////////////////////////////////////////// - -PlugAddressSpecificData::PlugAddressSpecificData( EPlugDirection plugDirection, - EPlugAddressMode plugAddressMode, - UnitPlugSpecificDataPlugAddress& unitPlugAddress ) - : m_plugDirection( plugDirection ) - , m_addressMode( plugAddressMode ) - , m_plugAddressData( new UnitPlugSpecificDataPlugAddress( unitPlugAddress ) ) -{ -} - -PlugAddressSpecificData::PlugAddressSpecificData( EPlugDirection plugDirection, - EPlugAddressMode plugAddressMode, - SubunitPlugSpecificDataPlugAddress& subUnitPlugAddress ) - : m_plugDirection( plugDirection ) - , m_addressMode( plugAddressMode ) - , m_plugAddressData( new SubunitPlugSpecificDataPlugAddress( subUnitPlugAddress ) ) -{ -} - -PlugAddressSpecificData::PlugAddressSpecificData( EPlugDirection plugDirection, - EPlugAddressMode plugAddressMode, - FunctionBlockPlugSpecificDataPlugAddress& functionBlockPlugAddress ) - : m_plugDirection( plugDirection ) - , m_addressMode( plugAddressMode ) - , m_plugAddressData( new FunctionBlockPlugSpecificDataPlugAddress( functionBlockPlugAddress ) ) -{ -} - -PlugAddressSpecificData::PlugAddressSpecificData( const PlugAddressSpecificData& pa ) - : m_plugDirection( pa.m_plugDirection ) - , m_addressMode( pa.m_addressMode ) - , m_plugAddressData( dynamic_cast( pa.m_plugAddressData->clone() ) ) -{ -} - -PlugAddressSpecificData::~PlugAddressSpecificData() -{ - delete m_plugAddressData; - m_plugAddressData = 0; -} - -bool -PlugAddressSpecificData::serialize( IOSSerialize& se ) -{ - se.write( m_plugDirection, "PlugAddressSpecificData plugDirection" ); - se.write( m_addressMode, "PlugAddressSpecificData addressMode" ); - return m_plugAddressData->serialize( se ); -} - -bool -PlugAddressSpecificData::deserialize( IISDeserialize& de ) -{ - de.read( &m_plugDirection ); - de.read( &m_addressMode ); - if ( m_plugAddressData ) { - delete m_plugAddressData; - m_plugAddressData = 0; - } - switch ( m_addressMode ) { - case ePAM_Unit: - m_plugAddressData = - new UnitPlugSpecificDataPlugAddress( - UnitPlugSpecificDataPlugAddress::ePT_PCR, - 0xff ); - break; - case ePAM_Subunit: - m_plugAddressData = - new SubunitPlugSpecificDataPlugAddress( - AVCCommand::eST_Reserved, - 0xff, - 0xff ); - break; - case ePAM_FunctionBlock: - m_plugAddressData = - new FunctionBlockPlugSpecificDataPlugAddress( - AVCCommand::eST_Reserved, - 0xff, - 0xff, - 0xff, - 0xff); - break; - default: - m_plugAddressData = - new UndefinedPlugSpecificDataPlugAddress(); - } - - return m_plugAddressData->deserialize( de ); -} - -PlugAddressSpecificData* -PlugAddressSpecificData::clone() const -{ - return new PlugAddressSpecificData( *this ); -} - - Index: trunk/libffado/src/libavc/avc_generic.h =================================================================== --- trunk/libffado/src/libavc/avc_generic.h (revision 445) +++ (revision ) @@ -1,149 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#ifndef AVCGENERIC_H -#define AVCGENERIC_H - -#include "avc_definitions.h" -#include "debugmodule/debugmodule.h" - -#include "../fbtypes.h" - -#include - -class IOSSerialize; -class IISDeserialize; -class Ieee1394Service; - -const int fcpFrameMaxLength = 512; -typedef unsigned char fcp_frame_t[fcpFrameMaxLength]; - -class IBusData { -public: - IBusData() {} - virtual ~IBusData() {} - - virtual bool serialize( IOSSerialize& se ) = 0; - virtual bool deserialize( IISDeserialize& de ) = 0; - - virtual IBusData* clone() const = 0; - -protected: - DECLARE_DEBUG_MODULE; -}; - -class AVCCommand -{ -public: - enum EResponse { - eR_Unknown = 0, - eR_NotImplemented = AVC1394_RESP_NOT_IMPLEMENTED, - eR_Accepted = AVC1394_RESP_ACCEPTED, - eR_Rejected = AVC1394_RESP_REJECTED, - eR_InTransition = AVC1394_RESP_IN_TRANSITION, - eR_Implemented = AVC1394_RESP_IMPLEMENTED, - eR_Changed = AVC1394_RESP_CHANGED, - eR_Interim = AVC1394_RESP_INTERIM, - }; - - enum ECommandType { - eCT_Control = AVC1394_CTYP_CONTROL, - eCT_Status = AVC1394_CTYP_STATUS, - eCT_SpecificInquiry = AVC1394_CTYP_SPECIFIC_INQUIRY, - eCT_Notify = AVC1394_CTYP_NOTIFY, - eCT_GeneralInquiry = AVC1394_CTYP_GENERAL_INQUIRY, - eCT_Unknown = 0xff, - }; - - enum ESubunitType { - eST_Monitor = AVC1394_SUBUNIT_VIDEO_MONITOR, - eST_Audio = AVC1394_SUBUNIT_AUDIO, - eST_Printer = AVC1394_SUBUNIT_PRINTER, - eST_Disc = AVC1394_SUBUNIT_DISC_RECORDER, - eST_VCR = AVC1394_SUBUNIT_VCR, - eST_Tuner = AVC1394_SUBUNIT_TUNER, - eST_CA = AVC1394_SUBUNIT_CA, - eST_Camera = AVC1394_SUBUNIT_VIDEO_CAMERA, - eST_Panel = AVC1394_SUBUNIT_PANEL, - eST_BulltinBoard = AVC1394_SUBUNIT_BULLETIN_BOARD, - eST_CameraStorage = AVC1394_SUBUNIT_CAMERA_STORAGE, - eST_Music = AVC1394_SUBUNIT_MUSIC, - eST_VendorUnique = AVC1394_SUBUNIT_VENDOR_UNIQUE, - eST_Reserved = AVC1394_SUBUNIT_RESERVED, - eST_Extended = AVC1394_SUBUNIT_EXTENDED, - eST_Unit = AVC1394_SUBUNIT_UNIT, - }; - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - - virtual bool setCommandType( ECommandType commandType ); - virtual bool fire(); - - EResponse getResponse(); - - bool setNodeId( fb_nodeid_t nodeId ); - bool setSubunitType( ESubunitType subunitType ); - bool setSubunitId( subunit_id_t subunitId ); - - ESubunitType getSubunitType(); - subunit_id_t getSubunitId(); - - bool setVerbose( int verboseLevel ); - int getVerboseLevel(); - - virtual const char* getCmdName() const = 0; - - // workaround - static void setSleepAfterAVCCommand( int time ); -protected: - void showFcpFrame( const unsigned char* buf, - unsigned short frameSize ) const; - -protected: - AVCCommand( Ieee1394Service& ieee1394service, opcode_t opcode ); - virtual ~AVCCommand() {} - - ECommandType getCommandType(); - - Ieee1394Service* m_p1394Service; - fb_nodeid_t m_nodeId; - - fcp_frame_t m_fcpFrame; - -private: - ctype_t m_ctype; - subunit_t m_subunit; - opcode_t m_opcode; - EResponse m_eResponse; - ECommandType m_commandType; - static int m_time; - - DECLARE_DEBUG_MODULE; -}; - - -const char* subunitTypeToString( subunit_type_t subunitType ); -const char* responseToString( AVCCommand::EResponse eResponse ); - -#endif // AVCGENERIC_H Index: trunk/libffado/src/libavc/avc_plug_info.cpp =================================================================== --- trunk/libffado/src/libavc/avc_plug_info.cpp (revision 445) +++ (revision ) @@ -1,143 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "avc_plug_info.h" -#include "avc_serialize.h" -#include "libieee1394/ieee1394service.h" - -#include -#include - -using namespace std; - -PlugInfoCmd::PlugInfoCmd( Ieee1394Service& ieee1394service, - ESubFunction eSubFunction ) - : AVCCommand( ieee1394service, AVC1394_CMD_PLUG_INFO ) - , m_serialBusIsochronousInputPlugs( 0xff ) - , m_serialBusIsochronousOutputPlugs( 0xff ) - , m_externalInputPlugs( 0xff ) - , m_externalOutputPlugs( 0xff ) - , m_serialBusAsynchronousInputPlugs( 0xff ) - , m_serialBusAsynchronousOuputPlugs( 0xff ) - , m_destinationPlugs( 0xff ) - , m_sourcePlugs( 0xff ) - , m_subFunction( eSubFunction ) -{ -} - -PlugInfoCmd::PlugInfoCmd( const PlugInfoCmd& rhs ) - : AVCCommand( rhs ) - , m_serialBusIsochronousInputPlugs( rhs.m_serialBusIsochronousInputPlugs ) - , m_serialBusIsochronousOutputPlugs( rhs.m_serialBusIsochronousOutputPlugs ) - , m_externalInputPlugs( rhs.m_externalInputPlugs ) - , m_externalOutputPlugs( rhs.m_externalOutputPlugs ) - , m_serialBusAsynchronousInputPlugs( rhs.m_serialBusAsynchronousInputPlugs ) - , m_serialBusAsynchronousOuputPlugs( rhs.m_serialBusAsynchronousOuputPlugs ) - , m_destinationPlugs( rhs.m_destinationPlugs ) - , m_sourcePlugs( rhs.m_sourcePlugs ) - , m_subFunction( rhs.m_subFunction ) -{ -} - -PlugInfoCmd::~PlugInfoCmd() -{ -} - -bool -PlugInfoCmd::serialize( IOSSerialize& se ) -{ - byte_t reserved = 0xff; - - AVCCommand::serialize( se ); - se.write( m_subFunction, "PlugInfoCmd subFunction" ); - switch( getSubunitType() ) { - case eST_Unit: - switch( m_subFunction ) { - case eSF_SerialBusIsochronousAndExternalPlug: - se.write( m_serialBusIsochronousInputPlugs, "PlugInfoCmd serialBusIsochronousInputPlugs" ); - se.write( m_serialBusIsochronousOutputPlugs, "PlugInfoCmd serialBusIsochronousOutputPlugs" ); - se.write( m_externalInputPlugs, "PlugInfoCmd externalInputPlugs" ); - se.write( m_externalOutputPlugs, "PlugInfoCmd externalOutputPlugs" ); - break; - case eSF_SerialBusAsynchonousPlug: - se.write( m_serialBusAsynchronousInputPlugs, "PlugInfoCmd serialBusAsynchronousInputPlugs" ); - se.write( m_serialBusAsynchronousOuputPlugs, "PlugInfoCmd serialBusAsynchronousOuputPlugs" ); - se.write( reserved, "PlugInfoCmd" ); - se.write( reserved, "PlugInfoCmd" ); - break; - default: - cerr << "Could not serialize with subfucntion " << m_subFunction << endl; - return false; - } - break; - default: - se.write( m_destinationPlugs, "PlugInfoCmd destinationPlugs" ); - se.write( m_sourcePlugs, "PlugInfoCmd sourcePlugs" ); - se.write( reserved, "PlugInfoCmd" ); - se.write( reserved, "PlugInfoCmd" ); - } - return true; -} - -bool -PlugInfoCmd::deserialize( IISDeserialize& de ) -{ - byte_t reserved; - - AVCCommand::deserialize( de ); - de.read( &m_subFunction ); - switch ( getSubunitType() ) { - case eST_Unit: - switch ( m_subFunction ) { - case eSF_SerialBusIsochronousAndExternalPlug: - de.read( &m_serialBusIsochronousInputPlugs ); - de.read( &m_serialBusIsochronousOutputPlugs ); - de.read( &m_externalInputPlugs ); - de.read( &m_externalOutputPlugs ); - break; - case eSF_SerialBusAsynchonousPlug: - de.read( &m_serialBusAsynchronousInputPlugs ); - de.read( &m_serialBusAsynchronousOuputPlugs ); - de.read( &reserved ); - de.read( &reserved ); - break; - default: - cerr << "Could not deserialize with subfunction " << m_subFunction << endl; - return false; - } - break; - default: - de.read( &m_destinationPlugs ); - de.read( &m_sourcePlugs ); - de.read( &reserved ); - de.read( &reserved ); - } - return true; -} - -bool -PlugInfoCmd::setSubFunction( ESubFunction subFunction ) -{ - m_subFunction = subFunction; - return true; -} Index: trunk/libffado/src/libavc/avc_extended_stream_format.cpp =================================================================== --- trunk/libffado/src/libavc/avc_extended_stream_format.cpp (revision 445) +++ (revision ) @@ -1,389 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "avc_extended_stream_format.h" -#include "avc_serialize.h" -#include "libieee1394/ieee1394service.h" - -#include - -/////////////////////////////////////////////////////////// -std::ostream& operator<<( std::ostream& stream, StreamFormatInfo info ) -{ -/* stream << info.m_freq << " Hz ("; - if ( info.m_format ) { - stream << "sync "; - } else { - stream << "compound "; - } - stream << "stream, "; - stream << "audio channels: " << info.m_audioChannels - << ", midi channels: " << info.m_midiChannels << ")"; -*/ - stream << " NbChannels " << (int)info.m_numberOfChannels << ", Format " << (int)info.m_streamFormat; - return stream; -} - -StreamFormatInfo::StreamFormatInfo() - : IBusData() -{ -} - -bool -StreamFormatInfo::serialize( IOSSerialize& se ) -{ - se.write( m_numberOfChannels, "StreamFormatInfo numberOfChannels" ); - se.write( m_streamFormat, "StreamFormatInfo streamFormat" ); - return true; -} - -bool -StreamFormatInfo::deserialize( IISDeserialize& de ) -{ - de.read( &m_numberOfChannels ); - de.read( &m_streamFormat ); - return true; -} - -StreamFormatInfo* -StreamFormatInfo::clone() const -{ - return new StreamFormatInfo( *this ); -} - -//////////////////////////////////////////////////////////// - -FormatInformationStreamsSync::FormatInformationStreamsSync() - : FormatInformationStreams() - , m_reserved0( 0xff ) - , m_samplingFrequency( eSF_DontCare ) - , m_rateControl( eRC_DontCare ) - , m_reserved1( 0xff ) -{ -} - -bool -FormatInformationStreamsSync::serialize( IOSSerialize& se ) -{ - se.write( m_reserved0, "FormatInformationStreamsSync reserved" ); - - // we have to clobber some bits - byte_t operand = ( m_samplingFrequency << 4 ) | 0x0e; - if ( m_rateControl == eRC_DontCare) { - operand |= 0x1; - } - se.write( operand, "FormatInformationStreamsSync sampling frequency and rate control" ); - - se.write( m_reserved1, "FormatInformationStreamsSync reserved" ); - return true; -} - -bool -FormatInformationStreamsSync::deserialize( IISDeserialize& de ) -{ - de.read( &m_reserved0 ); - - byte_t operand; - de.read( &operand ); - m_samplingFrequency = operand >> 4; - m_rateControl = operand & 0x01; - - de.read( &m_reserved1 ); - return true; -} - -FormatInformationStreamsSync* -FormatInformationStreamsSync::clone() const -{ - return new FormatInformationStreamsSync( *this ); -} - -//////////////////////////////////////////////////////////// -std::ostream& operator<<( std::ostream& stream, FormatInformationStreamsCompound info ) -{ - stream << (int)info.m_samplingFrequency << " Hz (rate control: "; - stream << (int)info.m_rateControl << ")" << std::endl; - - for ( FormatInformationStreamsCompound::StreamFormatInfoVector::iterator it = info.m_streamFormatInfos.begin(); - it != info.m_streamFormatInfos.end(); - ++it ) - { - StreamFormatInfo* sfi=*it; - stream << " > " << *sfi << std::endl; - } - - return stream; -} - -FormatInformationStreamsCompound::FormatInformationStreamsCompound() - : FormatInformationStreams() - , m_samplingFrequency( eSF_DontCare ) - , m_rateControl( eRC_DontCare ) - , m_numberOfStreamFormatInfos( 0 ) -{ -} - -FormatInformationStreamsCompound::~FormatInformationStreamsCompound() -{ - for ( StreamFormatInfoVector::iterator it = m_streamFormatInfos.begin(); - it != m_streamFormatInfos.end(); - ++it ) - { - delete *it; - } -} - -bool -FormatInformationStreamsCompound::serialize( IOSSerialize& se ) -{ - se.write( m_samplingFrequency, "FormatInformationStreamsCompound samplingFrequency" ); - se.write( m_rateControl, "FormatInformationStreamsCompound rateControl" ); - se.write( m_numberOfStreamFormatInfos, "FormatInformationStreamsCompound numberOfStreamFormatInfos" ); - for ( StreamFormatInfoVector::iterator it = m_streamFormatInfos.begin(); - it != m_streamFormatInfos.end(); - ++it ) - { - ( *it )->serialize( se ); - } - return true; -} - -bool -FormatInformationStreamsCompound::deserialize( IISDeserialize& de ) -{ - de.read( &m_samplingFrequency ); - de.read( &m_rateControl ); - de.read( &m_numberOfStreamFormatInfos ); - for ( int i = 0; i < m_numberOfStreamFormatInfos; ++i ) { - StreamFormatInfo* streamFormatInfo = new StreamFormatInfo; - if ( !streamFormatInfo->deserialize( de ) ) { - return false; - } - m_streamFormatInfos.push_back( streamFormatInfo ); - } - return true; -} - -FormatInformationStreamsCompound* -FormatInformationStreamsCompound::clone() const -{ - return new FormatInformationStreamsCompound( *this ); -} - -//////////////////////////////////////////////////////////// - -FormatInformation::FormatInformation() - : IBusData() - , m_root( eFHR_Invalid ) - , m_level1( eFHL1_AUDIOMUSIC_DONT_CARE ) - , m_level2( eFHL2_AM824_DONT_CARE ) - , m_streams( 0 ) -{ -} - -FormatInformation::FormatInformation( const FormatInformation& rhs ) - : IBusData() - , m_root( rhs.m_root ) - , m_level1( rhs.m_level1 ) - , m_level2( rhs.m_level2 ) - , m_streams( 0 ) -{ - if ( rhs.m_streams ) { - m_streams = dynamic_cast( rhs.m_streams->clone() ); - } -} - -FormatInformation::~FormatInformation() -{ - delete m_streams; - m_streams = 0; -} - -bool -FormatInformation::serialize( IOSSerialize& se ) -{ - if ( m_root != eFHR_Invalid ) { - se.write( m_root, "FormatInformation hierarchy root" ); - if ( m_level1 != eFHL1_AUDIOMUSIC_DONT_CARE ) { - se.write( m_level1, "FormatInformation hierarchy level 1" ); - if ( m_level2 != eFHL2_AM824_DONT_CARE ) { - se.write( m_level2, "FormatInformation hierarchy level 2" ); - } - } - } - if ( m_streams ) { - return m_streams->serialize( se ); - } - return true; -} - -bool -FormatInformation::deserialize( IISDeserialize& de ) -{ - bool result = false; - - delete m_streams; - m_streams = 0; - - // this code just parses BeBoB replies. - de.read( &m_root ); - - // just parse an audio and music hierarchy - if ( m_root == eFHR_AudioMusic ) { - de.read( &m_level1 ); - - switch ( m_level1 ) { - case eFHL1_AUDIOMUSIC_AM824: - { - // note: compound streams don't have a second level - de.read( &m_level2 ); - - if (m_level2 == eFHL2_AM824_SYNC_STREAM ) { - m_streams = new FormatInformationStreamsSync(); - result = m_streams->deserialize( de ); - } else { - // anything but the sync stream workds currently. - printf( "could not parse format information. (format hierarchy level 2 not recognized)\n" ); - } - } - break; - case eFHL1_AUDIOMUSIC_AM824_COMPOUND: - { - m_streams = new FormatInformationStreamsCompound(); - result = m_streams->deserialize( de ); - } - break; - default: - printf( "could not parse format information. (format hierarchy level 1 not recognized)\n" ); - } - } - - return result; -} - -FormatInformation* -FormatInformation::clone() const -{ - return new FormatInformation( *this ); -} - -//////////////////////////////////////////////////////////// - -ExtendedStreamFormatCmd::ExtendedStreamFormatCmd( Ieee1394Service& service, - ESubFunction eSubFunction ) - : AVCCommand( service, AVC1394_STREAM_FORMAT_SUPPORT ) - , m_subFunction( eSubFunction ) - , m_status( eS_NotUsed ) - , m_indexInStreamFormat( 0 ) - , m_formatInformation( new FormatInformation ) -{ - UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, 0x00 ); - m_plugAddress = new PlugAddress( PlugAddress::ePD_Output, PlugAddress::ePAM_Unit, unitPlugAddress ); -} - -ExtendedStreamFormatCmd::ExtendedStreamFormatCmd( - const ExtendedStreamFormatCmd& rhs ) - : AVCCommand( rhs ) -{ - m_subFunction = rhs.m_subFunction; - m_plugAddress = new PlugAddress( *rhs.m_plugAddress ); - m_formatInformation = - new FormatInformation( *rhs.m_formatInformation ); -} - -ExtendedStreamFormatCmd::~ExtendedStreamFormatCmd() -{ - delete m_plugAddress; - m_plugAddress = 0; - delete m_formatInformation; - m_formatInformation = 0; -} - -bool -ExtendedStreamFormatCmd::setPlugAddress( const PlugAddress& plugAddress ) -{ - delete m_plugAddress; - m_plugAddress = plugAddress.clone(); - return true; -} - -bool -ExtendedStreamFormatCmd::setIndexInStreamFormat( const int index ) -{ - m_indexInStreamFormat = index; - return true; -} - -bool -ExtendedStreamFormatCmd::serialize( IOSSerialize& se ) -{ - AVCCommand::serialize( se ); - se.write( m_subFunction, "ExtendedStreamFormatCmd subFunction" ); - m_plugAddress->serialize( se ); - se.write( m_status, "ExtendedStreamFormatCmd status" ); - if ( m_subFunction == eSF_ExtendedStreamFormatInformationCommandList ) { - se.write( m_indexInStreamFormat, "indexInStreamFormat" ); - } - m_formatInformation->serialize( se ); - return true; -} - -bool -ExtendedStreamFormatCmd::deserialize( IISDeserialize& de ) -{ - AVCCommand::deserialize( de ); - de.read( &m_subFunction ); - m_plugAddress->deserialize( de ); - de.read( &m_status ); - if ( m_subFunction == eSF_ExtendedStreamFormatInformationCommandList ) { - de.read( &m_indexInStreamFormat ); - } - m_formatInformation->deserialize( de ); - return true; -} - -ExtendedStreamFormatCmd::EStatus -ExtendedStreamFormatCmd::getStatus() -{ - EStatus status = static_cast( m_status ); - return status; -} - -FormatInformation* -ExtendedStreamFormatCmd::getFormatInformation() -{ - return m_formatInformation; -} - -ExtendedStreamFormatCmd::index_in_stream_format_t -ExtendedStreamFormatCmd::getIndex() -{ - return m_indexInStreamFormat; -} - -bool -ExtendedStreamFormatCmd::setSubFunction( ESubFunction subFunction ) -{ - m_subFunction = subFunction; - return true; -} Index: trunk/libffado/src/libavc/avc_extended_subunit_info.cpp =================================================================== --- trunk/libffado/src/libavc/avc_extended_subunit_info.cpp (revision 445) +++ (revision ) @@ -1,157 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "avc_extended_subunit_info.h" -#include "avc_serialize.h" -#include "libieee1394/ieee1394service.h" - -#include - -#define NR_OF_PAGE_DATA 5 -#define SIZE_OF_PAGE_ENTRY 5 - -ExtendedSubunitInfoPageData::ExtendedSubunitInfoPageData() - : IBusData() - , m_functionBlockType( 0xff ) - , m_functionBlockId( 0xff ) - , m_functionBlockSpecialPupose( eSP_NoSpecialPupose ) - , m_noOfInputPlugs( 0xff ) - , m_noOfOutputPlugs( 0xff ) -{ -} - -ExtendedSubunitInfoPageData::~ExtendedSubunitInfoPageData() -{ -} - -bool -ExtendedSubunitInfoPageData::serialize( IOSSerialize& se ) -{ - se.write( m_functionBlockType, "ExtendedSubunitInfoPageData: function block type" ); - se.write( m_functionBlockId, "ExtendedSubunitInfoPageData: function block id" ); - se.write( m_functionBlockSpecialPupose, "ExtendedSubunitInfoPageData: function block special purpose" ); - se.write( m_noOfInputPlugs, "ExtendedSubunitInfoPageData: number of input plugs" ); - se.write( m_noOfOutputPlugs, "ExtendedSubunitInfoPageData: number of output plugs" ); - - return true; -} - -bool -ExtendedSubunitInfoPageData::deserialize( IISDeserialize& de ) -{ - de.read( &m_functionBlockType ); - de.read( &m_functionBlockId ); - de.read( &m_functionBlockSpecialPupose ); - de.read( &m_noOfInputPlugs ); - de.read( &m_noOfOutputPlugs ); - return true; -} - -ExtendedSubunitInfoPageData* -ExtendedSubunitInfoPageData::clone() const -{ - return new ExtendedSubunitInfoPageData( *this ); -} - -////////////////////////////////////////////// - -ExtendedSubunitInfoCmd::ExtendedSubunitInfoCmd( Ieee1394Service& ieee1394service ) - : AVCCommand( ieee1394service, AVC1394_CMD_SUBUNIT_INFO ) - , m_page( 0xff ) - , m_fbType( eFBT_AllFunctinBlockType ) -{ -} - -ExtendedSubunitInfoCmd::ExtendedSubunitInfoCmd( const ExtendedSubunitInfoCmd& rhs ) - : AVCCommand( rhs ) - , m_page( rhs.m_page ) - , m_fbType( rhs.m_fbType ) -{ - for ( ExtendedSubunitInfoPageDataVector::const_iterator it = - rhs.m_infoPageDatas.begin(); - it != rhs.m_infoPageDatas.end(); - ++it ) - { - m_infoPageDatas.push_back( ( *it )->clone() ); - } -} - -ExtendedSubunitInfoCmd::~ExtendedSubunitInfoCmd() -{ - for ( ExtendedSubunitInfoPageDataVector::iterator it = - m_infoPageDatas.begin(); - it != m_infoPageDatas.end(); - ++it ) - { - delete *it; - } -} - -bool -ExtendedSubunitInfoCmd::serialize( IOSSerialize& se ) -{ - bool status = false; - status = AVCCommand::serialize( se ); - status &= se.write( m_page, "ExtendedSubunitInfoCmd: page" ); - status &= se.write( m_fbType, "ExtendedSubunitInfoCmd: function block type" ); - for ( ExtendedSubunitInfoPageDataVector::const_iterator it = - m_infoPageDatas.begin(); - it != m_infoPageDatas.end(); - ++it ) - { - status &= ( *it )->serialize( se ); - } - - int startIndex = m_infoPageDatas.size() * SIZE_OF_PAGE_ENTRY; - int endIndex = SIZE_OF_PAGE_ENTRY * NR_OF_PAGE_DATA; - for ( int i = startIndex; i < endIndex; ++i ) { - byte_t dummy = 0xff; - se.write( dummy, "ExtendedSubunitInfoCmd: space fill" ); - } - return status; -} - -bool -ExtendedSubunitInfoCmd::deserialize( IISDeserialize& de ) -{ - bool status = false; - status = AVCCommand::deserialize( de ); - status &= de.read( &m_page ); - status &= de.read( &m_fbType ); - for ( int i = 0; i < 5; ++i ) { - byte_t next; - de.peek( &next ); - if ( next != 0xff ) { - ExtendedSubunitInfoPageData* infoPageData = - new ExtendedSubunitInfoPageData(); - if ( !infoPageData->deserialize( de ) ) { - return false; - } - m_infoPageDatas.push_back( infoPageData ); - } else { - return status; - } - } - - return status; -} Index: trunk/libffado/src/libavc/avc_extended_cmd_generic.h =================================================================== --- trunk/libffado/src/libavc/avc_extended_cmd_generic.h (revision 445) +++ (revision ) @@ -1,289 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#ifndef AVCEXTENDEDCMDGENERIC_H -#define AVCEXTENDEDCMDGENERIC_H - -#include "avc_generic.h" - -//////////////////////////////////////////////////////////// - -class PlugAddressData : public IBusData { -}; - -//////////////////////////////////////////////////////////// - -class UnitPlugAddress : public PlugAddressData -{ -public: - enum EPlugType { - ePT_PCR = 0x00, - ePT_ExternalPlug = 0x01, - ePT_AsynchronousPlug = 0x02, - ePT_Unknown = 0xff, - }; - - UnitPlugAddress( EPlugType plugType, plug_type_t plugId ); - virtual ~UnitPlugAddress(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual UnitPlugAddress* clone() const; - - plug_id_t m_plugType; - plug_type_t m_plugId; - reserved_t m_reserved; -}; - -//////////////////////////////////////////////////////////// - -class SubunitPlugAddress : public PlugAddressData -{ -public: - SubunitPlugAddress( plug_id_t plugId ); - virtual ~SubunitPlugAddress(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual SubunitPlugAddress* clone() const; - - plug_id_t m_plugId; - reserved_t m_reserved0; - reserved_t m_reserved1; -}; - - -//////////////////////////////////////////////////////////// - -class FunctionBlockPlugAddress : public PlugAddressData -{ -public: - FunctionBlockPlugAddress( function_block_type_t functionBlockType, - function_block_id_t functionBlockId, - plug_id_t plugId ); - virtual ~FunctionBlockPlugAddress(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual FunctionBlockPlugAddress* clone() const; - - function_block_type_t m_functionBlockType; - function_block_id_t m_functionBlockId; - plug_id_t m_plugId; -}; - -//////////////////////////////////////////////////////////// - -class UndefinedPlugAddress : public PlugAddressData -{ -public: - UndefinedPlugAddress(); - virtual ~UndefinedPlugAddress(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual UndefinedPlugAddress* clone() const; - - reserved_t m_reserved0; - reserved_t m_reserved1; - reserved_t m_reserved2; -}; - -//////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////// - -class UnitPlugSpecificDataPlugAddress : public PlugAddressData -{ -public: - enum EPlugType { - ePT_PCR = 0x00, - ePT_ExternalPlug = 0x01, - ePT_AsynchronousPlug = 0x02, - }; - - UnitPlugSpecificDataPlugAddress( EPlugType plugType, - plug_type_t plugId ); - virtual ~UnitPlugSpecificDataPlugAddress(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual UnitPlugSpecificDataPlugAddress* clone() const; - - plug_type_t m_plugType; - plug_id_t m_plugId; - reserved_t m_reserved0; - reserved_t m_reserved1; - reserved_t m_reserved2; -}; - -//////////////////////////////////////////////////////////// - -class SubunitPlugSpecificDataPlugAddress : public PlugAddressData -{ -public: - SubunitPlugSpecificDataPlugAddress( AVCCommand::ESubunitType subunitType, - subunit_id_t subunitId, - plug_id_t plugId ); - virtual ~SubunitPlugSpecificDataPlugAddress(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual SubunitPlugSpecificDataPlugAddress* clone() const; - - subunit_type_t m_subunitType; - subunit_id_t m_subunitId; - plug_id_t m_plugId; - reserved_t m_reserved0; - reserved_t m_reserved1; -}; - -//////////////////////////////////////////////////////////// - -class FunctionBlockPlugSpecificDataPlugAddress : public PlugAddressData -{ -public: - FunctionBlockPlugSpecificDataPlugAddress( AVCCommand::ESubunitType subunitType, - subunit_id_t subunitId, - function_block_type_t functionBlockType, - function_block_id_t functionBlockId, - plug_id_t plugId); - virtual ~FunctionBlockPlugSpecificDataPlugAddress(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual FunctionBlockPlugSpecificDataPlugAddress* clone() const; - - subunit_type_t m_subunitType; - subunit_id_t m_subunitId; - function_block_type_t m_functionBlockType; - function_block_id_t m_functionBlockId; - plug_id_t m_plugId; -}; - -//////////////////////////////////////////////////////////// - -class UndefinedPlugSpecificDataPlugAddress : public PlugAddressData -{ -public: - UndefinedPlugSpecificDataPlugAddress(); - virtual ~UndefinedPlugSpecificDataPlugAddress(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual UndefinedPlugSpecificDataPlugAddress* clone() const; - - reserved_t m_reserved0; - reserved_t m_reserved1; - reserved_t m_reserved2; - reserved_t m_reserved3; - reserved_t m_reserved4; -}; - -//////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////// - -class PlugAddress : public IBusData { -public: - enum EPlugDirection { - ePD_Input = 0x00, - ePD_Output = 0x01, - ePD_Undefined = 0xff, - }; - - enum EPlugAddressMode { - ePAM_Unit = 0x00, - ePAM_Subunit = 0x01, - ePAM_FunctionBlock = 0x02, - ePAM_Undefined = 0xff, - }; - - PlugAddress( EPlugDirection plugDirection, - EPlugAddressMode plugAddressMode, - UnitPlugAddress& unitPlugAddress ); - PlugAddress( EPlugDirection plugDirection, - EPlugAddressMode plugAddressMode, - SubunitPlugAddress& subUnitPlugAddress ); - PlugAddress( EPlugDirection plugDirection, - EPlugAddressMode plugAddressMode, - FunctionBlockPlugAddress& functionBlockPlugAddress ); - PlugAddress( ); // undefined plug address - PlugAddress( const PlugAddress& pa ); - - virtual ~PlugAddress(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - - virtual PlugAddress* clone() const; - - plug_direction_t m_plugDirection; - plug_address_mode_t m_addressMode; - PlugAddressData* m_plugAddressData; -}; - -const char* plugAddressPlugDirectionToString( PlugAddress::EPlugDirection direction ); -const char* plugAddressAddressModeToString( PlugAddress::EPlugAddressMode mode ); - -//////////////////////////////////////////////////////////// - -class PlugAddressSpecificData : public IBusData { -public: - enum EPlugDirection { - ePD_Input = 0x00, - ePD_Output = 0x01, - }; - - enum EPlugAddressMode { - ePAM_Unit = 0x00, - ePAM_Subunit = 0x01, - ePAM_FunctionBlock = 0x02, - ePAM_Undefined = 0xff, - }; - - PlugAddressSpecificData( EPlugDirection plugDirection, - EPlugAddressMode plugAddressMode, - UnitPlugSpecificDataPlugAddress& unitPlugAddress ); - PlugAddressSpecificData( EPlugDirection plugDirection, - EPlugAddressMode plugAddressMode, - SubunitPlugSpecificDataPlugAddress& subUnitPlugAddress ); - PlugAddressSpecificData( EPlugDirection plugDirection, - EPlugAddressMode plugAddressMode, - FunctionBlockPlugSpecificDataPlugAddress& functionBlockPlugAddress ); - PlugAddressSpecificData( EPlugDirection plugDirection, - EPlugAddressMode plugAddressMode ); - PlugAddressSpecificData( const PlugAddressSpecificData& pa ); - - virtual ~PlugAddressSpecificData(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - - virtual PlugAddressSpecificData* clone() const; - - plug_direction_t m_plugDirection; - plug_address_mode_t m_addressMode; - PlugAddressData* m_plugAddressData; -}; - - -#endif Index: trunk/libffado/src/libavc/avc_plug_info.h =================================================================== --- trunk/libffado/src/libavc/avc_plug_info.h (revision 445) +++ (revision ) @@ -1,75 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#ifndef AVCPLUGINFO_H -#define AVCPLUGINFO_H - -#include "avc_generic.h" - -#include - -#define AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_ISOCHRONOUS_AND_EXTERNAL_PLUG 0x00 -#define AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_ASYNCHRONOUS_PLUG 0x01 -#define AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_GENERIC_BUS_PLUG_BLUETOOTH 0x40 -#define AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_NOT_USED 0xFF - - -class PlugInfoCmd: public AVCCommand -{ -public: - enum ESubFunction { - eSF_SerialBusIsochronousAndExternalPlug = AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_ISOCHRONOUS_AND_EXTERNAL_PLUG, - eSF_SerialBusAsynchonousPlug = AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_ASYNCHRONOUS_PLUG, - eSF_SerialBusPlug = AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_GENERIC_BUS_PLUG_BLUETOOTH, - eSF_NotUsed = AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_NOT_USED, - }; - - PlugInfoCmd( Ieee1394Service& ieee1394service, - ESubFunction eSubFunction = eSF_SerialBusIsochronousAndExternalPlug ); - PlugInfoCmd( const PlugInfoCmd& rhs ); - virtual ~PlugInfoCmd(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - - virtual const char* getCmdName() const - { return "PlugInfoCmd"; } - - nr_of_plugs_t m_serialBusIsochronousInputPlugs; - nr_of_plugs_t m_serialBusIsochronousOutputPlugs; - nr_of_plugs_t m_externalInputPlugs; - nr_of_plugs_t m_externalOutputPlugs; - nr_of_plugs_t m_serialBusAsynchronousInputPlugs; - nr_of_plugs_t m_serialBusAsynchronousOuputPlugs; - nr_of_plugs_t m_destinationPlugs; - nr_of_plugs_t m_sourcePlugs; - - bool setSubFunction( ESubFunction subFunction ); - -protected: - subfunction_t m_subFunction; - -}; - - -#endif // AVCPLUGINFO_H Index: trunk/libffado/src/libavc/avc_serialize.cpp =================================================================== --- trunk/libffado/src/libavc/avc_serialize.cpp (revision 445) +++ (revision ) @@ -1,171 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "avc_serialize.h" - -#include -#include - -#include - -IMPL_DEBUG_MODULE( CoutSerializer, CoutSerializer, DEBUG_LEVEL_NORMAL ); - -bool -CoutSerializer::write( byte_t d, const char* name ) -{ - debugOutput( DEBUG_LEVEL_NORMAL, " %3d:\t0x%02x\t%s\n", m_cnt, d, name ); - m_cnt += sizeof( byte_t ); - - return true; -} - -bool -CoutSerializer::write( quadlet_t d, const char* name ) -{ - debugOutput( DEBUG_LEVEL_NORMAL, " %3d:\t0x%08x\t%s\n", m_cnt, d, name ); - m_cnt += sizeof( quadlet_t ); - return true; -} - -////////////////////////////////////////////////// - -bool -StringSerializer::write( byte_t d, const char* name ) -{ - char* result; - asprintf( &result, " %3d:\t0x%02x\t%s\n", m_cnt, d, name ); - - m_string += result; - free( result ); - - m_cnt += sizeof( byte_t ); - - return true; -} - -bool -StringSerializer::write( quadlet_t d, const char* name ) -{ - char* result; - asprintf( &result, " %3d:\t0x%08x\t%s\n", m_cnt, d, name ); - - m_string += result; - free( result ); - - m_cnt += sizeof( quadlet_t ); - return true; -} - -////////////////////////////////////////////////// - -bool -BufferSerialize::write( byte_t value, const char* name ) -{ - bool result = false; - if ( isCurPosValid() ) { - *m_curPos = value; - m_curPos += sizeof( byte_t ); - result = true; - } - return result; -} - -bool -BufferSerialize::write( quadlet_t value, const char* name ) -{ - bool result = false; - if ( isCurPosValid() ) { - * ( quadlet_t* )m_curPos = value; - m_curPos += sizeof( quadlet_t ); - result = true; - } - return result; -} - -bool -BufferSerialize::isCurPosValid() const -{ - if ( static_cast( ( m_curPos - m_buffer ) ) >= m_length ) { - return false; - } - return true; -} - -////////////////////////////////////////////////// - -bool -BufferDeserialize::read( byte_t* value ) -{ - bool result = false; - if ( isCurPosValid() ) { - *value = *m_curPos; - m_curPos += sizeof( byte_t ); - result = true; - } - return result; -} - -bool -BufferDeserialize::read( quadlet_t* value ) -{ - bool result = false; - if ( isCurPosValid() ) { - *value = *( ( quadlet_t* )m_curPos ); - m_curPos += sizeof( quadlet_t ); - result = true; - } - return result; -} - -bool -BufferDeserialize::read( char** value, size_t length ) -{ - bool result = false; - if ( isCurPosValid() ) { - *value = ( char* )m_curPos; - m_curPos += length; - result = true; - } - return result; -} - -bool -BufferDeserialize::peek( byte_t* value ) -{ - bool result = false; - if ( isCurPosValid() ) { - *value = *m_curPos; - result = true; - } - return result; -} - -bool -BufferDeserialize::isCurPosValid() const -{ - if ( static_cast( ( m_curPos - m_buffer ) ) >= m_length ) { - return false; - } - return true; -} - Index: trunk/libffado/src/libavc/avc_extended_stream_format.h =================================================================== --- trunk/libffado/src/libavc/avc_extended_stream_format.h (revision 445) +++ (revision ) @@ -1,289 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#ifndef AVCEXTENDEDSTREAMFROMAT_H -#define AVCEXTENDEDSTREAMFROMAT_H - -#include "avc_generic.h" -#include "avc_extended_cmd_generic.h" - -#include -#include -#include - -#define AVC1394_STREAM_FORMAT_SUPPORT 0x2F -#define AVC1394_STREAM_FORMAT_SUBFUNCTION_INPUT 0x00 -#define AVC1394_STREAM_FORMAT_SUBFUNCTION_OUTPUT 0x01 - -// BridgeCo extensions -#define AVC1394_STREAM_FORMAT_SUBFUNCTION_EXTENDED_STREAM_FORMAT 0xC0 -#define AVC1394_STREAM_FORMAT_SUBFUNCTION_EXTENDED_STREAM_FORMAT_LIST 0xC1 - - -#define AVC1394_STREAM_FORMAT_HIERARCHY_ROOT_DVCR 0x80 -#define AVC1394_STREAM_FORMAT_HIERARCHY_ROOT_AUDIOMUSIC 0x90 -#define AVC1394_STREAM_FORMAT_HIERARCHY_ROOT_INVALID 0xFF - -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_SD525_60 0x00 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_SDL525_60 0x04 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_HD1125_60 0x08 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_SD625_60 0x80 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_SDL625_50 0x84 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_HD1250_50 0x88 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_AM824 0x00 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_24_4_AUDIO_PACK 0x01 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_32_FLOATING_POINT_DATA 0x02 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_AM824_COMPOUND 0x40 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_DONT_CARE 0xFF - - -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC60968_3 0x00 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_3 0x01 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_4 0x02 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_5 0x03 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_6 0x04 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_7 0x05 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_MULTI_BIT_LINEAR_AUDIO_RAW 0x06 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_MULTI_BIT_LINEAR_AUDIO_DVD_AUDIO 0x07 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_ONE_BIT_AUDIO_PLAIN_RAW 0x08 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_ONE_BIT_AUDIO_PLAIN_SACD 0x09 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_ONE_BIT_AUDIO_ENCODED_RAW 0x0A -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_ONE_BIT_AUDIO_ENCODED_SACD 0x0B -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_HIGH_PRECISION_MULTIBIT_LINEAR_AUDIO 0x0C -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_MIDI_CONFORMANT 0x0D -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_SYNC_STREAM 0x40 -#define AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_DONT_CARE 0xFF - -#define AVC1394_STREAM_FORMAT_AM824_IEC60968_3 0x00 -#define AVC1394_STREAM_FORMAT_AM824_IEC61937_3 0x01 -#define AVC1394_STREAM_FORMAT_AM824_IEC61937_4 0x02 -#define AVC1394_STREAM_FORMAT_AM824_IEC61937_5 0x03 -#define AVC1394_STREAM_FORMAT_AM824_IEC61937_6 0x04 -#define AVC1394_STREAM_FORMAT_AM824_IEC61937_7 0x05 -#define AVC1394_STREAM_FORMAT_AM824_MULTI_BIT_LINEAR_AUDIO_RAW 0x06 -#define AVC1394_STREAM_FORMAT_AM824_MULTI_BIT_LINEAR_AUDIO_DVD_AUDIO 0x07 -#define AVC1394_STREAM_FORMAT_AM824_HIGH_PRECISION_MULTIBIT_LINEAR_AUDIO 0x0C -#define AVC1394_STREAM_FORMAT_AM824_MIDI_CONFORMANT 0x0D -#define AVC1394_STREAM_FORMAT_AM824_DONT_CARE 0xFF - -/* -// As defined in 'AV/C Stream Format Information Specification 1.0 TA Document 2001002' -// Not used for extended stream format -#define AVC1394_STREAM_FORMAT_SUPPORT_STATUS_SUPPORTED_AND_CONFIGURED 0x00 -#define AVC1394_STREAM_FORMAT_SUPPORT_STATUS_SUPPORTED_AND_HAS_NOT_BEEN_CONFIGURED 0x01 -#define AVC1394_STREAM_FORMAT_SUPPORT_STATUS_SUPPORTED_AND_READY_TO_CONFIGURE 0x02 -#define AVC1394_STREAM_FORMAT_SUPPORT_STATUS_SUPPORTED_AND_NOT_CONFIGURED 0x03 -#define AVC1394_STREAM_FORMAT_SUPPORT_STATUS_NOT_SUPPORTED 0x04 -// 0x05 - 0xFE reserved -#define AVC1394_STREAM_FORMAT_SUPPORT_STATUS_NO_INFORMATION 0xFF -*/ - -#define AVC1394_EXTENDED_STREAM_FORMAT_INFO_STATUS_ACTIVE 0x00 -#define AVC1394_EXTENDED_STREAM_FORMAT_INFO_STATUS_INACTIVE 0x01 -#define AVC1394_EXTENDED_STREAM_FORMAT_INFO_STATUS_NO_STREAM_FORMAT 0x02 -#define AVC1394_EXTENDED_STREAM_FORMAT_INFO_STATUS_NOT_USED 0xff - -class IOSSerialize; -class IISDeserialize; - -enum ERateControl { - eRC_Supported = 0x00, - eRC_DontCare = 0x01, -}; - -//////////////////////////////////////////////////////////// - -class StreamFormatInfo: public IBusData -{ -public: - StreamFormatInfo(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - - virtual StreamFormatInfo* clone() const; - - number_of_channels_t m_numberOfChannels; - stream_format_t m_streamFormat; -}; -std::ostream& operator<<( std::ostream& stream, StreamFormatInfo info ); - -//////////////////////////////////////////////////////////// - -class FormatInformationStreams: public IBusData -{ -public: - FormatInformationStreams() {} - virtual ~FormatInformationStreams() {} -}; - -//////////////////////////////////////////////////////////// - -class FormatInformationStreamsSync: public FormatInformationStreams -{ -public: - FormatInformationStreamsSync(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual FormatInformationStreamsSync* clone() const; - - reserved_t m_reserved0; - sampling_frequency_t m_samplingFrequency; - rate_control_t m_rateControl; - reserved_t m_reserved1; -}; - -//////////////////////////////////////////////////////////// - -class FormatInformationStreamsCompound: public FormatInformationStreams -{ -public: - FormatInformationStreamsCompound(); - virtual ~FormatInformationStreamsCompound(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual FormatInformationStreamsCompound* clone() const; - - sampling_frequency_t m_samplingFrequency; - rate_control_t m_rateControl; - number_of_stream_format_infos_t m_numberOfStreamFormatInfos; - - typedef std::vector< StreamFormatInfo* > StreamFormatInfoVector; - StreamFormatInfoVector m_streamFormatInfos; -}; -std::ostream& operator<<( std::ostream& stream, FormatInformationStreamsCompound info ); - - -//////////////////////////////////////////////////////////// - -class FormatInformation: public IBusData -{ -public: - enum EFormatHierarchyRoot { - eFHR_DVCR = AVC1394_STREAM_FORMAT_HIERARCHY_ROOT_DVCR, - eFHR_AudioMusic = AVC1394_STREAM_FORMAT_HIERARCHY_ROOT_AUDIOMUSIC, - eFHR_Invalid = AVC1394_STREAM_FORMAT_HIERARCHY_ROOT_INVALID, - }; - - enum EFomatHierarchyLevel1 { - eFHL1_DVCR_SD525_60 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_SD525_60, - eFHL1_DVCR_SDL525_60 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_SDL525_60, - eFHL1_DVCR_HD1125_60 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_HD1125_60, - eFHL1_DVCR_SD625_60 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_SD625_60, - eFHL1_DVCR_SDL625_50 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_SDL625_50, - eFHL1_DVCR_HD1250_50 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_DVCR_HD1250_50, - eFHL1_AUDIOMUSIC_AM824 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_AM824, - eFHL1_AUDIOMUSIC_24_4_AUDIO_PACK = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_24_4_AUDIO_PACK, - eFHL1_AUDIOMUSIC_32_FLOATING = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_32_FLOATING_POINT_DATA, - eFHL1_AUDIOMUSIC_AM824_COMPOUND = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_AM824_COMPOUND, - eFHL1_AUDIOMUSIC_DONT_CARE = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_1_AUDIOMUSIC_DONT_CARE, - }; - - enum EFormatHierarchyLevel2 { - eFHL2_AM824_IEC60968_3 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC60968_3, - eFHL2_AM824_IEC61937_3 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_3, - eFHL2_AM824_IEC61937_4 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_4, - eFHL2_AM824_IEC61937_5 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_5, - eFHL2_AM824_IEC61937_6 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_6, - eFHL2_AM824_IEC61937_7 = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_IEC61937_7, - eFHL2_AM824_MULTI_BIT_LINEAR_AUDIO_RAW = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_MULTI_BIT_LINEAR_AUDIO_RAW, - eFHL2_AM824_MULTI_BIT_LINEAR_AUDIO_DVD_AUDIO = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_MULTI_BIT_LINEAR_AUDIO_DVD_AUDIO, - eFHL2_AM824_ONE_BIT_AUDIO_PLAIN_RAW = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_ONE_BIT_AUDIO_PLAIN_RAW, - eFHL2_AM824_ONE_BIT_AUDIO_PLAIN_SACD = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_ONE_BIT_AUDIO_PLAIN_SACD, - eFHL2_AM824_ONE_BIT_AUDIO_ENCODED_RAW = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_ONE_BIT_AUDIO_ENCODED_RAW, - eFHL2_AM824_ONE_BIT_AUDIO_ENCODED_SACD = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_ONE_BIT_AUDIO_ENCODED_SACD, - eFHL2_AM824_HIGH_PRECISION_MULTIBIT_LINEAR_AUDIO = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_HIGH_PRECISION_MULTIBIT_LINEAR_AUDIO, - eFHL2_AM824_MIDI_CONFORMANT = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_MIDI_CONFORMANT, - eFHL2_AM824_SYNC_STREAM = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_SYNC_STREAM, - eFHL2_AM824_DONT_CARE = AVC1394_STREAM_FORMAT_HIERARCHY_LEVEL_2_AM824_DONT_CARE, - }; - - typedef byte_t format_hierarchy_root_t; - typedef byte_t format_hierarchy_level1_t; - typedef byte_t format_hierarchy_level2_t; - - FormatInformation(); - FormatInformation( const FormatInformation& rhs ); - virtual ~FormatInformation(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - - virtual FormatInformation* clone() const; - - format_hierarchy_root_t m_root; - format_hierarchy_level1_t m_level1; - format_hierarchy_level2_t m_level2; - FormatInformationStreams* m_streams; -}; - -/////////////////////////////////////////////////////////// - -class ExtendedStreamFormatCmd: public AVCCommand -{ -public: - enum ESubFunction { - eSF_Input = AVC1394_STREAM_FORMAT_SUBFUNCTION_INPUT, - eSF_Output = AVC1394_STREAM_FORMAT_SUBFUNCTION_OUTPUT, - eSF_ExtendedStreamFormatInformationCommand = AVC1394_STREAM_FORMAT_SUBFUNCTION_EXTENDED_STREAM_FORMAT, - eSF_ExtendedStreamFormatInformationCommandList = AVC1394_STREAM_FORMAT_SUBFUNCTION_EXTENDED_STREAM_FORMAT_LIST, - }; - - enum EStatus { - eS_Active = AVC1394_EXTENDED_STREAM_FORMAT_INFO_STATUS_ACTIVE, - eS_Inactive = AVC1394_EXTENDED_STREAM_FORMAT_INFO_STATUS_INACTIVE, - eS_NoStreamFormat = AVC1394_EXTENDED_STREAM_FORMAT_INFO_STATUS_NO_STREAM_FORMAT, - eS_NotUsed = AVC1394_EXTENDED_STREAM_FORMAT_INFO_STATUS_NOT_USED, - }; - typedef byte_t status_t; - typedef byte_t index_in_stream_format_t; - - ExtendedStreamFormatCmd( Ieee1394Service& ieee1349service, ESubFunction eSubFunction = eSF_ExtendedStreamFormatInformationCommand ); - ExtendedStreamFormatCmd( const ExtendedStreamFormatCmd& rhs ); - virtual ~ExtendedStreamFormatCmd(); - - bool setPlugAddress( const PlugAddress& plugAddress ); - bool setIndexInStreamFormat( const int index ); - bool setSubFunction( ESubFunction subFunction ); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - - EStatus getStatus(); - FormatInformation* getFormatInformation(); - index_in_stream_format_t getIndex(); - - virtual const char* getCmdName() const - { return "ExtendedStreamFormatCmd"; } - -protected: - subfunction_t m_subFunction; - PlugAddress* m_plugAddress; - status_t m_status; - index_in_stream_format_t m_indexInStreamFormat; - FormatInformation* m_formatInformation; -}; - -#endif // AVCEXTENDEDSTREAMFROMAT_H Index: trunk/libffado/src/libavc/avc_extended_subunit_info.h =================================================================== --- trunk/libffado/src/libavc/avc_extended_subunit_info.h (revision 445) +++ (revision ) @@ -1,107 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#ifndef AVCEXTENDEDSUBUNITINFO_H -#define AVCEXTENDEDSUBUNITINFO_H - -#include "avc_generic.h" - -#include - -#include -#include - -class ExtendedSubunitInfoPageData: public IBusData -{ - public: - enum ESpecialPurpose { - eSP_InputGain = 0x00, - eSP_OutputVolume = 0x01, - eSP_NoSpecialPupose = 0xff, - }; - - ExtendedSubunitInfoPageData(); - virtual ~ExtendedSubunitInfoPageData(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual ExtendedSubunitInfoPageData* clone() const; - - function_block_type_t m_functionBlockType; - function_block_id_t m_functionBlockId; - function_block_special_purpose_t m_functionBlockSpecialPupose; - no_of_input_plugs_t m_noOfInputPlugs; - no_of_output_plugs_t m_noOfOutputPlugs; -}; - -typedef std::vector ExtendedSubunitInfoPageDataVector; - -class ExtendedSubunitInfoCmd: public AVCCommand -{ -public: - enum EFunctionBlockType { - eFBT_AllFunctinBlockType = 0xff, - eFBT_AudioSubunitSelector = 0x80, - eFBT_AudioSubunitFeature = 0x81, - eFBT_AudioSubunitProcessing = 0x82, - eFBT_AudioSubunitCodec = 0x83, - }; - - enum EProcessingType { - ePT_Unknown = 0x00, - ePT_Mixer = 0x01, - ePT_Generic = 0x02, - ePT_UpDown = 0x03, - ePT_DolbyProLogic = 0x04, - ePT_3DStereoExtender = 0x05, - ePT_Reverberation = 0x06, - ePT_Chorus = 0x07, - ePT_DynamicRangeCompression = 0x08, - ePT_EnhancedMixer = 0x82, - ePT_Reserved = 0xff, - }; - - enum ECodecType { - eCT_AC3Decoder = 0x01, - eCT_MPEGDecoder = 0x02, - eCT_DTSDecoder = 0x03, - eCT_Reserved = 0xff, - - }; - - ExtendedSubunitInfoCmd( Ieee1394Service& ieee1394service ); - ExtendedSubunitInfoCmd( const ExtendedSubunitInfoCmd& rhs ); - virtual ~ExtendedSubunitInfoCmd(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - - virtual const char* getCmdName() const - { return "ExtendedSubunitInfoCmd"; } - - page_t m_page; - function_block_type_t m_fbType; - ExtendedSubunitInfoPageDataVector m_infoPageDatas; -}; - -#endif Index: trunk/libffado/src/libavc/avc_connect.cpp =================================================================== --- trunk/libffado/src/libavc/avc_connect.cpp (revision 445) +++ (revision ) @@ -1,54 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "avc_connect.h" -#include "avc_serialize.h" -#include "libieee1394/ieee1394service.h" - -#include -#include - -using namespace std; - -ConnectCmd::ConnectCmd(Ieee1394Service& ieee1394service) - : AVCCommand( ieee1394service, AVC1394_CMD_CONNECT ) -{ -} - -ConnectCmd::~ConnectCmd() -{ -} - -bool -ConnectCmd::serialize( IOSSerialize& se ) -{ - AVCCommand::serialize( se ); - return true; -} - -bool -ConnectCmd::deserialize( IISDeserialize& de ) -{ - AVCCommand::deserialize( de ); - return true; -} Index: trunk/libffado/src/libavc/avc_unit_info.cpp =================================================================== --- trunk/libffado/src/libavc/avc_unit_info.cpp (revision 445) +++ (revision ) @@ -1,85 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "avc_unit_info.h" -#include "avc_serialize.h" -#include "libieee1394/ieee1394service.h" - -#include -#include - -using namespace std; - -UnitInfoCmd::UnitInfoCmd( Ieee1394Service& ieee1349service ) - : AVCCommand( ieee1349service, AVC1394_CMD_UNIT_INFO ) - , m_reserved( 0xff ) - , m_unit_type( 0xff ) - , m_unit( 0xff ) - , m_company_id( 0xffffffff ) -{ -} - -UnitInfoCmd::~UnitInfoCmd() -{ -} - -bool -UnitInfoCmd::serialize( IOSSerialize& se ) -{ - AVCCommand::serialize( se ); - - se.write( m_reserved, "UnitInfoCmd reserved" ); - byte_t operand = ( m_unit_type << 3 ) | ( m_unit & 0x7 ); - se.write( operand, "UnitInfoCmd unit_type and unit" ); - operand = ( m_company_id >> 16 ) & 0xff; - se.write( operand, "UnitInfoCmd company_ID (2)" ); - operand = ( m_company_id >> 8 ) & 0xff; - se.write( operand, "UnitInfoCmd company_ID (1)" ); - operand = ( m_company_id >> 0 ) & 0xff; - se.write( operand, "UnitInfoCmd company_ID (0)" ); - - return true; -} - -bool -UnitInfoCmd::deserialize( IISDeserialize& de ) -{ - AVCCommand::deserialize( de ); - - de.read( &m_reserved ); - - byte_t operand; - de.read( &operand ); - m_unit_type = ( operand >> 3 ); - m_unit = ( operand & 0x7 ); - - de.read( &operand ); - m_company_id = 0; - m_company_id |= operand << 16; - de.read( &operand ); - m_company_id |= operand << 8; - de.read( &operand ); - m_company_id |= operand; - - return true; -} Index: trunk/libffado/src/libavc/avc_serialize.h =================================================================== --- trunk/libffado/src/libavc/avc_serialize.h (revision 445) +++ (revision ) @@ -1,144 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#ifndef SERIALIZE_H -#define SERIALIZE_H - -#include "debugmodule/debugmodule.h" - -#include // byte_t and quadlet_t declaration -#include - -// Interfaces - -class IOSSerialize { -public: - IOSSerialize() {} - virtual ~IOSSerialize() {} - - virtual bool write( byte_t value, const char* name = "" ) = 0; - virtual bool write( quadlet_t value, const char* name = "" ) = 0; -}; - -class IISDeserialize { -public: - IISDeserialize() {} - virtual ~IISDeserialize() {} - - virtual bool read( byte_t* value ) = 0; - virtual bool read( quadlet_t* value ) = 0; - virtual bool read( char** value, size_t length ) = 0; - virtual bool peek( byte_t* value ) = 0; -}; - -// Specialized implementations of previously defined interfaces - -class CoutSerializer: public IOSSerialize { -public: - CoutSerializer() - : IOSSerialize() - , m_cnt( 0 ) - {} - virtual ~CoutSerializer() {} - - virtual bool write( byte_t value, const char* name = "" ); - virtual bool write( quadlet_t value, const char* name = "" ); - -private: - unsigned int m_cnt; - DECLARE_DEBUG_MODULE; - -}; - -class StringSerializer: public IOSSerialize { -public: - StringSerializer() - : IOSSerialize() - , m_cnt( 0 ) - {} - virtual ~StringSerializer() {} - - virtual bool write( byte_t value, const char* name = "" ); - virtual bool write( quadlet_t value, const char* name = "" ); - virtual std::string getString( ) { return m_string;}; - -private: - unsigned int m_cnt; - std::string m_string; - -}; - -class BufferSerialize: public IOSSerialize { -public: - BufferSerialize( unsigned char* buffer, size_t length ) - : IOSSerialize() - , m_buffer( buffer ) - , m_curPos( m_buffer ) - , m_length( length ) - {} - virtual ~BufferSerialize() {} - - virtual bool write( byte_t value, const char* name = "" ); - virtual bool write( quadlet_t value, const char* name = "" ); - - int getNrOfProducesBytes() const - { return m_curPos - m_buffer; } - -protected: - inline bool isCurPosValid() const; - -private: - unsigned char* m_buffer; - unsigned char* m_curPos; - size_t m_length; -}; - -class BufferDeserialize: public IISDeserialize { -public: - BufferDeserialize( const unsigned char* buffer, size_t length ) - : IISDeserialize() - , m_buffer( const_cast( buffer ) ) - , m_curPos( m_buffer ) - , m_length( length ) - {} - virtual ~BufferDeserialize() {} - - virtual bool read( byte_t* value ); - virtual bool read( quadlet_t* value ); - virtual bool read( char** value, size_t length ); - virtual bool peek( byte_t* value ); - - int getNrOfConsumedBytes() const - { return m_curPos - m_buffer; } - -protected: - inline bool isCurPosValid() const; - -private: - unsigned char* m_buffer; // start of the buffer - unsigned char* m_curPos; // current read pos - size_t m_length; // size of buffer -}; - -#endif // SERIALIZE_H - Index: trunk/libffado/src/libavc/avc_signal_source.cpp =================================================================== --- trunk/libffado/src/libavc/avc_signal_source.cpp (revision 445) +++ (revision ) @@ -1,284 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "avc_signal_source.h" -#include "avc_serialize.h" -#include "libieee1394/ieee1394service.h" - -#include -#include - -using namespace std; - -#define AVC1394_CMD_SIGNAL_SOURCE 0x1A - -SignalUnitAddress::SignalUnitAddress() - : m_plugId( ePI_Invalid ) -{ -} - -bool -SignalUnitAddress::serialize( IOSSerialize& se ) -{ - byte_t reserved = 0xff; - se.write( reserved, "SignalUnitAddress" ); - se.write( m_plugId, "SignalUnitAddress plugId" ); - return true; -} - -bool -SignalUnitAddress::deserialize( IISDeserialize& de ) -{ - byte_t operand; - de.read( &operand ); - de.read( &m_plugId ); - return true; -} - -SignalUnitAddress* -SignalUnitAddress::clone() const -{ - return new SignalUnitAddress( *this ); -} - -//////////////////////////////////////// - -SignalSubunitAddress::SignalSubunitAddress() - : m_subunitType( AVC1394_SUBUNIT_RESERVED ) - , m_subunitId( AVC1394_SUBUNIT_ID_RESERVED ) - , m_plugId( ePI_Invalid ) -{ -} - -bool -SignalSubunitAddress::serialize( IOSSerialize& se ) -{ - byte_t operand = ( m_subunitType << 3 ) | ( m_subunitId & 0x7 ); - se.write( operand, "SignalSubunitAddress subunitType & subunitId" ); - se.write( m_plugId, "SignalSubunitAddress plugId" ); - return true; -} - -bool -SignalSubunitAddress::deserialize( IISDeserialize& de ) -{ - byte_t operand; - de.read( &operand ); - m_subunitType = operand >> 3; - m_subunitId = operand & 0x7; - de.read( &m_plugId ); - return true; -} - -SignalSubunitAddress* -SignalSubunitAddress::clone() const -{ - return new SignalSubunitAddress( *this ); -} - -//////////////////////////////////////// - - -SignalSourceCmd::SignalSourceCmd( Ieee1394Service& ieee1394service ) - : AVCCommand( ieee1394service, AVC1394_CMD_SIGNAL_SOURCE ) - , m_resultStatus( 0xff ) - , m_outputStatus( 0xff ) - , m_conv( 0xff ) - , m_signalStatus( 0xff ) - , m_signalSource( 0 ) - , m_signalDestination( 0 ) -{ -} - -SignalSourceCmd::~SignalSourceCmd() -{ - delete m_signalSource; - m_signalSource = 0; - delete m_signalDestination; - m_signalDestination = 0; -} - -bool -SignalSourceCmd::serialize( IOSSerialize& se ) -{ - AVCCommand::serialize( se ); - - byte_t operand; - switch ( getCommandType() ) { - case eCT_Status: - operand = ( m_outputStatus << 5 ) - | ( ( m_conv & 0x1 ) << 4 ) - | ( m_signalStatus & 0xf ); - se.write( operand, "SignalSourceCmd outputStatus & conv & signalStatus" ); - break; - case eCT_Control: - case eCT_SpecificInquiry: - operand = m_resultStatus & 0xf; - se.write( operand, "SignalSourceCmd resultStatus" ); - break; - default: - cerr << "Can't handle command type " << getCommandType() << endl; - return false; - } - - switch( getSubunitType() ) { - case eST_Unit: - case eST_Audio: - case eST_Music: - { - if ( m_signalSource ) { - m_signalSource->serialize( se ); - } else { - byte_t reserved = 0xff; - se.write( reserved, "SignalSourceCmd" ); - se.write( reserved, "SignalSourceCmd" ); - } - - if ( m_signalDestination ) { - m_signalDestination->serialize( se ); - } else { - byte_t reserved = 0xff; - se.write( reserved, "SignalSourceCmd" ); - se.write( reserved, "SignalSourceCmd" ); - } - } - break; - default: - cerr << "Can't handle subunit type " << getSubunitType() << endl; - return false; - } - - return true; -} - -bool -SignalSourceCmd::deserialize( IISDeserialize& de ) -{ - delete m_signalSource; - m_signalSource = 0; - delete m_signalDestination; - m_signalDestination = 0; - - AVCCommand::deserialize( de ); - - byte_t operand; - switch ( getCommandType() ) { - case eCT_Status: - de.read( &operand ); - m_outputStatus = operand >> 5; - m_conv = ( operand & 0x10 ) >> 4; - m_signalStatus = operand & 0xf; - break; - case eCT_Control: - case eCT_SpecificInquiry: - de.read( &operand ); - m_resultStatus = operand & 0xf; - break; - default: - cerr << "Can't handle command type " << getCommandType() << endl; - return false; - } - - switch( getSubunitType() ) { - case eST_Unit: - case eST_Audio: - case eST_Music: - { - byte_t operand; - de.peek( &operand ); - if ( operand == 0xff ) { - m_signalSource = new SignalUnitAddress; - } else { - m_signalSource = new SignalSubunitAddress; - } - - m_signalSource->deserialize( de ); - - de.peek( &operand ); - if ( operand == 0xff ) { - m_signalDestination = new SignalUnitAddress; - } else { - m_signalDestination = new SignalSubunitAddress; - } - m_signalDestination->deserialize( de ); - } - break; - default: - cerr << "Can't handle subunit type " << getSubunitType() << endl; - return false; - } - - return true; -} - -bool -SignalSourceCmd::setSignalSource( SignalUnitAddress& signalAddress ) -{ - if ( m_signalSource ) { - delete m_signalSource; - } - m_signalSource = signalAddress.clone(); - return true; -} - -bool -SignalSourceCmd::setSignalSource( SignalSubunitAddress& signalAddress ) -{ - if ( m_signalSource ) { - delete m_signalSource; - } - m_signalSource = signalAddress.clone(); - return true; -} - -bool -SignalSourceCmd::setSignalDestination( SignalUnitAddress& signalAddress ) -{ - if ( m_signalDestination ) { - delete m_signalDestination; - } - m_signalDestination = signalAddress.clone(); - return true; -} - -bool -SignalSourceCmd::setSignalDestination( SignalSubunitAddress& signalAddress ) -{ - if ( m_signalDestination ) { - delete m_signalDestination; - } - m_signalDestination = signalAddress.clone(); - return true; -} - -SignalAddress* -SignalSourceCmd::getSignalSource() -{ - return m_signalSource; -} - -SignalAddress* -SignalSourceCmd::getSignalDestination() -{ - return m_signalDestination; -} Index: trunk/libffado/src/libavc/avc_connect.h =================================================================== --- trunk/libffado/src/libavc/avc_connect.h (revision 445) +++ (revision ) @@ -1,45 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#ifndef AVCCONNECT_H -#define AVCCONNECT_H - -#include "avc_generic.h" - -#include - -class ConnectCmd: public AVCCommand -{ -public: - ConnectCmd(Ieee1394Service& ieee1394service); - virtual ~ConnectCmd(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - - virtual const char* getCmdName() const - { return "ConnectCmd"; } -}; - - -#endif // AVCCONNECT_H Index: trunk/libffado/src/libavc/avc_function_block.cpp =================================================================== --- trunk/libffado/src/libavc/avc_function_block.cpp (revision 455) +++ (revision ) @@ -1,703 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * Copyright (C) 2005-2007 by Pieter Palmers - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "avc_function_block.h" -#include "avc_serialize.h" -#include "libieee1394/ieee1394service.h" - -///////////////////////////////// - -FunctionBlockFeatureVolume::FunctionBlockFeatureVolume() - : IBusData() - , m_controlDataLength( 2 ) - , m_volume( 0 ) -{ -} - -FunctionBlockFeatureVolume::FunctionBlockFeatureVolume( const FunctionBlockFeatureVolume& rhs ) - : m_controlDataLength( rhs.m_controlDataLength ) - , m_volume( rhs.m_volume ) -{ -} - -FunctionBlockFeatureVolume::~FunctionBlockFeatureVolume() -{ -} - -bool -FunctionBlockFeatureVolume::serialize( IOSSerialize& se ) -{ - bool bStatus; - byte_t val; - bStatus = se.write( m_controlDataLength, "FunctionBlockFeatureVolume controlDataLength" ); - val = (byte_t)(m_volume >> 8); - bStatus &= se.write( val, "FunctionBlockFeatureVolume volume high" ); - val = m_volume & 0xff; - bStatus &= se.write( val, "FunctionBlockFeatureVolume volume low" ); - - return bStatus; -} - -bool -FunctionBlockFeatureVolume::deserialize( IISDeserialize& de ) -{ - bool bStatus; - byte_t val; - bStatus = de.read( &m_controlDataLength ); - bStatus &= de.read( &val ); - m_volume = val << 8; - bStatus &= de.read( &val ); - m_volume |= val; - - return bStatus; -} - -FunctionBlockFeatureVolume* -FunctionBlockFeatureVolume::clone() const -{ - return new FunctionBlockFeatureVolume( *this ); -} - -///////////////////////////////// - -FunctionBlockProcessingMixer::FunctionBlockProcessingMixer() - : IBusData() - , m_controlSelector( FunctionBlockProcessing::eCSE_Processing_Mixer ) -{ -} - -FunctionBlockProcessingMixer::FunctionBlockProcessingMixer( const FunctionBlockProcessingMixer& rhs ) - : m_controlSelector( rhs.m_controlSelector ) -{ -} - -FunctionBlockProcessingMixer::~FunctionBlockProcessingMixer() -{ -} - -bool -FunctionBlockProcessingMixer::serialize( IOSSerialize& se ) -{ - bool bStatus; - bStatus = se.write( m_controlSelector, "FunctionBlockProcessingMixer controlSelector" ); - - return bStatus; -} - -bool -FunctionBlockProcessingMixer::deserialize( IISDeserialize& de ) -{ - bool bStatus; - bStatus = de.read( &m_controlSelector ); - - return bStatus; -} - -FunctionBlockProcessingMixer* -FunctionBlockProcessingMixer::clone() const -{ - return new FunctionBlockProcessingMixer( *this ); -} - -///////////////////////////////// - -FunctionBlockProcessingEnhancedMixer::FunctionBlockProcessingEnhancedMixer() - : IBusData() - , m_controlSelector( FunctionBlockProcessing::eCSE_Processing_EnhancedMixer ) - , m_statusSelector( eSS_ProgramableState ) -{ -} - -FunctionBlockProcessingEnhancedMixer::FunctionBlockProcessingEnhancedMixer( - const FunctionBlockProcessingEnhancedMixer& rhs ) - : m_controlSelector( rhs.m_controlSelector ) - , m_statusSelector( rhs.m_statusSelector ) -{ -} - -FunctionBlockProcessingEnhancedMixer::~FunctionBlockProcessingEnhancedMixer() -{ -} - -bool -FunctionBlockProcessingEnhancedMixer::serialize( IOSSerialize& se ) -{ - int todo,done; - bool bStatus; - byte_t data_length_hi, data_length_lo; - - bStatus = se.write( m_controlSelector, "FunctionBlockProcessingEnhancedMixer controlSelector" ); - bStatus &= se.write( m_statusSelector, "FunctionBlockProcessingEnhancedMixer statusSelector" ); - - switch (m_statusSelector) { - case eSS_ProgramableState: - m_controlDataLength=m_LevelData.size(); - data_length_hi=(m_controlDataLength >> 8); - data_length_lo=(m_controlDataLength & 0xFF); - bStatus &= se.write( data_length_hi, "FunctionBlockProcessingEnhancedMixer controlDataLengthHi" ); - bStatus &= se.write( data_length_lo, "FunctionBlockProcessingEnhancedMixer controlDataLengthLo" ); - - for (int i=0;i> 8); - data_length_lo=(m_controlDataLength & 0xFF); - bStatus &= se.write( data_length_hi, "FunctionBlockProcessingEnhancedMixer controlDataLengthHi" ); - bStatus &= se.write( data_length_lo, "FunctionBlockProcessingEnhancedMixer controlDataLengthLo" ); - - for (int i=0;i> 8; - byte_t value_lo=value & 0xFF; - - bStatus &= se.write( value_hi, "FunctionBlockProcessingEnhancedMixer data" ); - bStatus &= se.write( value_lo, "FunctionBlockProcessingEnhancedMixer data" ); - } - break; - } - return bStatus; -} - -bool -FunctionBlockProcessingEnhancedMixer::deserialize( IISDeserialize& de ) -{ - int todo; - bool bStatus=true; - bStatus = de.read( &m_controlSelector ); - - // NOTE: the returned value is currently bogus, so overwrite it - m_controlSelector=FunctionBlockProcessing::eCSE_Processing_EnhancedMixer; - - bStatus &= de.read( &m_statusSelector ); - - byte_t data_length_hi; - byte_t data_length_lo; - bStatus &= de.read( &data_length_hi ); - bStatus &= de.read( &data_length_lo ); - - m_controlDataLength = (data_length_hi << 8) + data_length_lo; - switch (m_statusSelector) { - case eSS_ProgramableState: - m_ProgramableStateData.clear(); - for (int i=0;i=0;j--) { - byte_t bit_value; - bit_value=(((1<7-todo;j--) { - byte_t bit_value; - bit_value=(((1<serialize( se ); - } else { - bStatus = false; - } - - return bStatus; -} - -bool -FunctionBlockFeature::deserialize( IISDeserialize& de ) -{ - bool bStatus; - bStatus = de.read( &m_selectorLength ); - bStatus &= de.read( &m_audioChannelNumber ); - bStatus &= de.read( &m_controlSelector ); - - switch( m_controlSelector ) { - case eCSE_Feature_Volume: - bStatus &= m_pVolume->deserialize( de ); - break; - case eCSE_Feature_Mute: - case eCSE_Feature_LRBalance: - case eCSE_Feature_FRBalance: - case eCSE_Feature_Bass: - case eCSE_Feature_Mid: - case eCSE_Feature_Treble: - case eCSE_Feature_GEQ: - case eCSE_Feature_AGC: - case eCSE_Feature_Delay: - case eCSE_Feature_BassBoost: - case eCSE_Feature_Loudness: - default: - bStatus = false; - } - - return bStatus; -} - -FunctionBlockFeature* -FunctionBlockFeature::clone() const -{ - return new FunctionBlockFeature( *this ); -} - -///////////////////////////////// - -FunctionBlockProcessing::FunctionBlockProcessing() - : IBusData() - , m_selectorLength( 0x04 ) - , m_fbInputPlugNumber( 0x00 ) - , m_inputAudioChannelNumber( 0x00 ) - , m_outputAudioChannelNumber( 0x00 ) - , m_pMixer( 0 ) - , m_pEnhancedMixer( 0 ) -{ -} - -FunctionBlockProcessing::FunctionBlockProcessing( const FunctionBlockProcessing& rhs ) - : m_selectorLength( rhs.m_selectorLength ) - , m_fbInputPlugNumber( rhs.m_fbInputPlugNumber ) - , m_inputAudioChannelNumber( rhs.m_inputAudioChannelNumber ) - , m_outputAudioChannelNumber( rhs.m_outputAudioChannelNumber ) -{ - if ( rhs.m_pMixer ) { - m_pMixer = new FunctionBlockProcessingMixer( *rhs.m_pMixer ); - } else if ( rhs.m_pEnhancedMixer ) { - m_pEnhancedMixer = new FunctionBlockProcessingEnhancedMixer( *rhs.m_pEnhancedMixer ); - } -} - -FunctionBlockProcessing::~FunctionBlockProcessing() -{ - delete m_pMixer; - m_pMixer = 0; - delete m_pEnhancedMixer; - m_pEnhancedMixer = 0; -} - -bool -FunctionBlockProcessing::serialize( IOSSerialize& se ) -{ - bool bStatus; - bStatus = se.write( m_selectorLength, "FunctionBlockProcessing selectorLength" ); - bStatus &= se.write( m_fbInputPlugNumber, "FunctionBlockProcessing fbInputPlugNumber" ); - bStatus &= se.write( m_inputAudioChannelNumber, "FunctionBlockProcessing inputAudioChannelNumber" ); - bStatus &= se.write( m_outputAudioChannelNumber, "FunctionBlockProcessing outputAudioChannelNumber" ); - - if ( m_pMixer ) { - bStatus &= m_pMixer->serialize( se ); - } else if ( m_pEnhancedMixer ) { - bStatus &= m_pEnhancedMixer->serialize( se ); - } else { - bStatus = false; - } - - return bStatus; -} - -bool -FunctionBlockProcessing::deserialize( IISDeserialize& de ) -{ - // NOTE: apparently the fbCmd of the STATUS type, - // with EnhancedMixer controlSelector returns with this - // controlSelector type changed to Mixer, making it - // impossible to choose the correct response handler - // based upon the response only. - - // HACK: we assume that it is the same as the sent one - // we also look at our data structure to figure out what we sent - byte_t controlSelector=eCSE_Processing_Unknown; - if(m_pMixer) { - controlSelector=eCSE_Processing_Mixer; - } else if(m_pEnhancedMixer) { - controlSelector=eCSE_Processing_EnhancedMixer; - } - - bool bStatus; - bStatus = de.read( &m_selectorLength ); - bStatus &= de.read( &m_fbInputPlugNumber ); - bStatus &= de.read( &m_inputAudioChannelNumber ); - bStatus &= de.read( &m_outputAudioChannelNumber ); - - byte_t controlSelector_response; - bStatus &= de.peek( &controlSelector_response ); -/* debugOutput(DEBUG_LEVEL_VERBOSE,"ctrlsel: orig = %02X, resp = %02X\n", - controlSelector, controlSelector_response);*/ - - switch( controlSelector ) { - case eCSE_Processing_Mixer: - if ( !m_pMixer ) { - m_pMixer = new FunctionBlockProcessingMixer; - } - bStatus &= m_pMixer->deserialize( de ); - break; - case eCSE_Processing_EnhancedMixer: - if ( !m_pEnhancedMixer ) { - m_pEnhancedMixer = new FunctionBlockProcessingEnhancedMixer; - } - bStatus &= m_pEnhancedMixer->deserialize( de ); - break; - case eCSE_Processing_Enable: - case eCSE_Processing_Mode: - default: - bStatus = false; - } - - byte_t tmp; - if (de.peek(&tmp)) { - debugOutput(DEBUG_LEVEL_VERBOSE,"Unprocessed bytes:\n"); - while (de.read(&tmp)) { - debugOutput(DEBUG_LEVEL_VERBOSE," %02X\n",tmp); - } - } - - return bStatus; -} - -FunctionBlockProcessing* -FunctionBlockProcessing::clone() const -{ - return new FunctionBlockProcessing( *this ); -} - -///////////////////////////////// - -FunctionBlockCodec::FunctionBlockCodec() - : IBusData() -{ -} - -FunctionBlockCodec::FunctionBlockCodec( const FunctionBlockCodec& rhs ) - : IBusData() -{ -} - -FunctionBlockCodec::~FunctionBlockCodec() -{ -} - -bool -FunctionBlockCodec::serialize( IOSSerialize& se ) -{ - return false; -} - -bool -FunctionBlockCodec::deserialize( IISDeserialize& de ) -{ - return false; -} - -FunctionBlockCodec* -FunctionBlockCodec::clone() const -{ - return new FunctionBlockCodec( *this ); -} - -///////////////////////////////// -///////////////////////////////// - -FunctionBlockCmd::FunctionBlockCmd( Ieee1394Service& ieee1394service, - EFunctionBlockType eType, - function_block_id_t id, - EControlAttribute eCtrlAttrib ) - : AVCCommand( ieee1394service, AVC1394_FUNCTION_BLOCK_CMD ) - , m_functionBlockType( eType ) - , m_functionBlockId( id ) - , m_controlAttribute( eCtrlAttrib ) - , m_pFBSelector( 0 ) - , m_pFBFeature( 0 ) - , m_pFBProcessing( 0 ) - , m_pFBCodec( 0 ) -{ - setSubunitType( eST_Audio ); - - switch( m_functionBlockType ) { - case eFBT_Selector: - m_pFBSelector = new FunctionBlockSelector; - break; - case eFBT_Feature: - m_pFBFeature = new FunctionBlockFeature; - break; - case eFBT_Processing: - m_pFBProcessing = new FunctionBlockProcessing; - break; - case eFBT_Codec: - m_pFBCodec = new FunctionBlockCodec; - break; - } -} - -FunctionBlockCmd::FunctionBlockCmd( const FunctionBlockCmd& rhs ) - : AVCCommand( rhs ) - , m_functionBlockType( rhs.m_functionBlockType ) - , m_functionBlockId( rhs.m_functionBlockId ) - , m_controlAttribute( rhs.m_controlAttribute ) - , m_pFBSelector( new FunctionBlockSelector( *rhs.m_pFBSelector ) ) - , m_pFBFeature( new FunctionBlockFeature( *rhs.m_pFBFeature ) ) - , m_pFBProcessing( new FunctionBlockProcessing( *rhs.m_pFBProcessing ) ) - , m_pFBCodec( new FunctionBlockCodec( *rhs.m_pFBCodec ) ) -{ -} - -FunctionBlockCmd::~FunctionBlockCmd() -{ - delete m_pFBSelector; - m_pFBSelector = 0; - delete m_pFBFeature; - m_pFBFeature = 0; - delete m_pFBProcessing; - m_pFBProcessing = 0; - delete m_pFBCodec; - m_pFBCodec = 0; -} - -bool -FunctionBlockCmd::serialize( IOSSerialize& se ) -{ - bool bStatus; - bStatus = AVCCommand::serialize( se ); - bStatus &= se.write( m_functionBlockType, "FunctionBlockCmd functionBlockType" ); - bStatus &= se.write( m_functionBlockId, "FunctionBlockCmd functionBlockId" ); - bStatus &= se.write( m_controlAttribute, "FunctionBlockCmd controlAttribute" ); - - switch( m_functionBlockType ) { - case eFBT_Selector: - if ( m_pFBSelector ) { - bStatus &= m_pFBSelector->serialize( se ); - } else { - bStatus = false; - } - break; - case eFBT_Feature: - if ( m_pFBFeature ) { - bStatus &= m_pFBFeature->serialize( se ); - } else { - bStatus = false; - } - break; - case eFBT_Processing: - if ( m_pFBProcessing ) { - bStatus &= m_pFBProcessing->serialize( se ); - } else { - bStatus = false; - } - break; - case eFBT_Codec: - if ( m_pFBCodec ) { - bStatus &= m_pFBCodec->serialize( se ); - } else { - bStatus = false; - } - break; - default: - bStatus = false; - } - - return bStatus; -} - -bool -FunctionBlockCmd::deserialize( IISDeserialize& de ) -{ - bool bStatus; - bStatus = AVCCommand::deserialize( de ); - - bStatus &= de.read( &m_functionBlockType ); - bStatus &= de.read( &m_functionBlockId ); - bStatus &= de.read( &m_controlAttribute ); - - switch( m_functionBlockType ) { - case eFBT_Selector: - if ( !m_pFBSelector ) { - m_pFBSelector = new FunctionBlockSelector; - } - bStatus &= m_pFBSelector->deserialize( de ); - break; - case eFBT_Feature: - if ( !m_pFBFeature ) { - m_pFBFeature = new FunctionBlockFeature; - } - bStatus &= m_pFBFeature->deserialize( de ); - break; - case eFBT_Processing: - if ( !m_pFBProcessing ) { - m_pFBProcessing = new FunctionBlockProcessing; - } - bStatus &= m_pFBProcessing->deserialize( de ); - break; - case eFBT_Codec: - if ( !m_pFBCodec ) { - m_pFBCodec = new FunctionBlockCodec; - } - bStatus &= m_pFBCodec->deserialize( de ); - break; - default: - bStatus = false; - } - - return bStatus; -} - -FunctionBlockCmd* -FunctionBlockCmd::clone() const -{ - return new FunctionBlockCmd( *this ); -} Index: trunk/libffado/src/libavc/avc_unit_info.h =================================================================== --- trunk/libffado/src/libavc/avc_unit_info.h (revision 445) +++ (revision ) @@ -1,71 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#ifndef AVCUNITINFO_H -#define AVCUNITINFO_H - -#include "avc_generic.h" - -#include - -class UnitInfoCmd: public AVCCommand -{ -public: - - enum EUnitType { - eUT_Monitor = AVC1394_SUBUNIT_VIDEO_MONITOR, - eUT_Audio = AVC1394_SUBUNIT_AUDIO, - eUT_Printer = AVC1394_SUBUNIT_PRINTER, - eUT_Disc = AVC1394_SUBUNIT_DISC_RECORDER, - eUT_VCR = AVC1394_SUBUNIT_VCR, - eUT_Tuner = AVC1394_SUBUNIT_TUNER, - eUT_CA = AVC1394_SUBUNIT_CA, - eUT_Camera = AVC1394_SUBUNIT_VIDEO_CAMERA, - eUT_Panel = AVC1394_SUBUNIT_PANEL, - eUT_BulltinBoard = AVC1394_SUBUNIT_BULLETIN_BOARD, - eUT_CameraStorage = AVC1394_SUBUNIT_CAMERA_STORAGE, - eUT_Music = AVC1394_SUBUNIT_MUSIC, - eUT_VendorUnique = AVC1394_SUBUNIT_VENDOR_UNIQUE, - eUT_Reserved = AVC1394_SUBUNIT_RESERVED, - eUT_Extended = AVC1394_SUBUNIT_EXTENDED, - eUT_Unit = AVC1394_SUBUNIT_UNIT, - }; - - UnitInfoCmd( Ieee1394Service& ieee1349service ); - virtual ~UnitInfoCmd(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - - virtual const char* getCmdName() const - { return "UnitInfoCmd"; } - - reserved_t m_reserved; - unit_type_t m_unit_type; - unit_t m_unit; - - company_id_t m_company_id; -}; - - -#endif // AVCUNITINFO_H Index: trunk/libffado/src/libavc/avc_extended_plug_info.cpp =================================================================== --- trunk/libffado/src/libavc/avc_extended_plug_info.cpp (revision 445) +++ (revision ) @@ -1,856 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "avc_extended_plug_info.h" -#include "avc_serialize.h" -#include "libieee1394/ieee1394service.h" - -#include -#include - -using namespace std; - -///////////////////////////////////////// -///////////////////////////////////////// - -ExtendedPlugInfoPlugTypeSpecificData::ExtendedPlugInfoPlugTypeSpecificData( EExtendedPlugInfoPlugType ePlugType ) - : IBusData() - , m_plugType( ePlugType ) -{ -} - -ExtendedPlugInfoPlugTypeSpecificData::~ExtendedPlugInfoPlugTypeSpecificData() -{ -} - -bool -ExtendedPlugInfoPlugTypeSpecificData::serialize( IOSSerialize& se ) -{ - se.write( m_plugType, "ExtendedPlugInfoPlugTypeSpecificData plugType" ); - return true; -} - - -bool -ExtendedPlugInfoPlugTypeSpecificData::deserialize( IISDeserialize& de ) -{ - de.read( &m_plugType ); - return true; -} - -ExtendedPlugInfoPlugTypeSpecificData* ExtendedPlugInfoPlugTypeSpecificData::clone() const -{ - return new ExtendedPlugInfoPlugTypeSpecificData( *this ); -} - -const char* extendedPlugInfoPlugTypeStrings[] = -{ - "IsoStream", - "AsyncStream", - "Midi", - "Sync", - "Analog", - "Digital", - "Unknown", -}; - -const char* extendedPlugInfoPlugTypeToString( plug_type_t plugType ) -{ - if ( plugType > sizeof( extendedPlugInfoPlugTypeStrings ) ) { - return "Unknown"; - } else { - return extendedPlugInfoPlugTypeStrings[plugType]; - } -} - -///////////////////////////////////////// -///////////////////////////////////////// - -ExtendedPlugInfoPlugNameSpecificData::ExtendedPlugInfoPlugNameSpecificData() - : IBusData() -{ -} - -ExtendedPlugInfoPlugNameSpecificData::~ExtendedPlugInfoPlugNameSpecificData() -{ -} - -bool -ExtendedPlugInfoPlugNameSpecificData::serialize( IOSSerialize& se ) -{ - byte_t length = strlen( m_name.c_str() ); - se.write( length, - "ExtendedPlugInfoPlugNameSpecificData: string length" ); - for ( unsigned int i = 0; i < length; ++i ) { - se.write( static_cast( m_name[i] ), - "ExtendedPlugInfoPlugNameSpecificData: char" ); - } - - return true; -} - -bool -ExtendedPlugInfoPlugNameSpecificData::deserialize( IISDeserialize& de ) -{ - byte_t length; - de.read( &length ); - m_name.clear(); - char* name; - de.read( &name, length ); - m_name = name; - - return true; -} - -ExtendedPlugInfoPlugNameSpecificData::ExtendedPlugInfoPlugNameSpecificData* -ExtendedPlugInfoPlugNameSpecificData::clone() const -{ - return new ExtendedPlugInfoPlugNameSpecificData( *this ); -} - - -///////////////////////////////////////// -///////////////////////////////////////// - -ExtendedPlugInfoPlugNumberOfChannelsSpecificData::ExtendedPlugInfoPlugNumberOfChannelsSpecificData() - : IBusData() - , m_nrOfChannels( 0 ) -{ -} - -ExtendedPlugInfoPlugNumberOfChannelsSpecificData::~ExtendedPlugInfoPlugNumberOfChannelsSpecificData() -{ -} - -bool -ExtendedPlugInfoPlugNumberOfChannelsSpecificData::serialize( IOSSerialize& se ) -{ - se.write( m_nrOfChannels, - "ExtendedPlugInfoPlugNumberOfChannelsSpecificData: " - "number of channels" ); - return true; -} - -bool -ExtendedPlugInfoPlugNumberOfChannelsSpecificData::deserialize( IISDeserialize& de ) -{ - de.read( &m_nrOfChannels ); - return true; -} - -ExtendedPlugInfoPlugNumberOfChannelsSpecificData::ExtendedPlugInfoPlugNumberOfChannelsSpecificData* -ExtendedPlugInfoPlugNumberOfChannelsSpecificData::clone() const -{ - return new ExtendedPlugInfoPlugNumberOfChannelsSpecificData( *this ); -} - -///////////////////////////////////////// -///////////////////////////////////////// - -ExtendedPlugInfoPlugChannelPositionSpecificData::ExtendedPlugInfoPlugChannelPositionSpecificData() - : IBusData() - , m_nrOfClusters( 0 ) -{ -} - -ExtendedPlugInfoPlugChannelPositionSpecificData::~ExtendedPlugInfoPlugChannelPositionSpecificData() -{ -} - -bool -ExtendedPlugInfoPlugChannelPositionSpecificData::serialize( IOSSerialize& se ) -{ - se.write( m_nrOfClusters, - "ExtendedPlugInfoPlugChannelPositionSpecificData: " - "number of clusters" ); - - for ( ClusterInfoVector::const_iterator it = m_clusterInfos.begin(); - it != m_clusterInfos.end(); - ++it ) - { - const ClusterInfo* clusterInfo = &( *it ); - - se.write( clusterInfo->m_nrOfChannels, - "ExtendedPlugInfoPlugChannelPositionSpecificData: " - "number of channels" ); - for ( ChannelInfoVector::const_iterator cit - = clusterInfo->m_channelInfos.begin(); - cit != clusterInfo->m_channelInfos.end(); - ++cit ) - { - const ChannelInfo* channelInfo = &( *cit ); - se.write( channelInfo->m_streamPosition, - "ExtendedPlugInfoPlugChannelPositionSpecificData: " - "stream position" ); - se.write( channelInfo->m_location, - "ExtendedPlugInfoPlugChannelPositionSpecificData: " - "location" ); - } - } - - return true; -} - -bool -ExtendedPlugInfoPlugChannelPositionSpecificData::deserialize( IISDeserialize& de ) -{ - m_clusterInfos.clear(); - - de.read( &m_nrOfClusters ); - for ( int i = 0; i < m_nrOfClusters; ++i ) { - ClusterInfo clusterInfo; - de.read ( &clusterInfo.m_nrOfChannels ); - for ( int j = 0; j < clusterInfo.m_nrOfChannels; ++j ) { - ChannelInfo channelInfo; - de.read( &channelInfo.m_streamPosition ); - de.read( &channelInfo.m_location ); - clusterInfo.m_channelInfos.push_back( channelInfo ); - } - m_clusterInfos.push_back( clusterInfo ); - } - return true; -} - -ExtendedPlugInfoPlugChannelPositionSpecificData::ExtendedPlugInfoPlugChannelPositionSpecificData* -ExtendedPlugInfoPlugChannelPositionSpecificData::clone() const -{ - return new ExtendedPlugInfoPlugChannelPositionSpecificData( *this ); -} - -///////////////////////////////////////// -///////////////////////////////////////// - -ExtendedPlugInfoPlugChannelNameSpecificData::ExtendedPlugInfoPlugChannelNameSpecificData() - : IBusData() - , m_streamPosition( 0 ) - , m_stringLength( 0xff ) -{ -} - -ExtendedPlugInfoPlugChannelNameSpecificData::~ExtendedPlugInfoPlugChannelNameSpecificData() -{ -} - -bool -ExtendedPlugInfoPlugChannelNameSpecificData::serialize( IOSSerialize& se ) -{ - se.write( m_streamPosition, - "ExtendedPlugInfoPlugChannelNameSpecificData: stream position" ); - se.write( m_stringLength, - "ExtendedPlugInfoPlugChannelNameSpecificData: string length" ); - for ( unsigned int i = 0; i < m_plugChannelName.size(); ++i ) { - se.write( static_cast( m_plugChannelName[i] ), - "ExtendedPlugInfoPlugChannelNameSpecificData: char" ); - } - - return true; -} - -bool -ExtendedPlugInfoPlugChannelNameSpecificData::deserialize( IISDeserialize& de ) -{ - de.read( &m_streamPosition ); - de.read( &m_stringLength ); - - char* name = new char[m_stringLength+1]; - for ( int i = 0; i < m_stringLength; ++i ) { - byte_t c; - de.read( &c ); - // \todo do correct encoding - if ( c == '&' ) { - c = '+'; - } - name[i] = c; - } - name[m_stringLength] = '\0'; - m_plugChannelName = name; - delete[] name; - - return true; -} - -ExtendedPlugInfoPlugChannelNameSpecificData::ExtendedPlugInfoPlugChannelNameSpecificData* -ExtendedPlugInfoPlugChannelNameSpecificData::clone() const -{ - return new ExtendedPlugInfoPlugChannelNameSpecificData( *this ); -} - -///////////////////////////////////////// -///////////////////////////////////////// -ExtendedPlugInfoPlugInputSpecificData::ExtendedPlugInfoPlugInputSpecificData() - : IBusData() -{ - UnitPlugSpecificDataPlugAddress - unitPlug( UnitPlugSpecificDataPlugAddress::ePT_PCR, 0x00 ); - m_plugAddress - = new PlugAddressSpecificData( PlugAddressSpecificData::ePD_Output, - PlugAddressSpecificData::ePAM_Unit, - unitPlug ); -} - -ExtendedPlugInfoPlugInputSpecificData::ExtendedPlugInfoPlugInputSpecificData(const ExtendedPlugInfoPlugInputSpecificData& rhs ) -{ - m_plugAddress = rhs.m_plugAddress->clone(); -} - - -ExtendedPlugInfoPlugInputSpecificData::~ExtendedPlugInfoPlugInputSpecificData() -{ - delete m_plugAddress; - m_plugAddress = 0; -} - -bool -ExtendedPlugInfoPlugInputSpecificData::serialize( IOSSerialize& se ) -{ - if ( m_plugAddress ) { - return m_plugAddress->serialize( se ); - } else { - return false; - } -} - -bool -ExtendedPlugInfoPlugInputSpecificData::deserialize( IISDeserialize& de ) -{ - return m_plugAddress->deserialize( de ); -} - -ExtendedPlugInfoPlugInputSpecificData::ExtendedPlugInfoPlugInputSpecificData* -ExtendedPlugInfoPlugInputSpecificData::clone() const -{ - return new ExtendedPlugInfoPlugInputSpecificData( *this ); -} - -///////////////////////////////////////// -///////////////////////////////////////// - -ExtendedPlugInfoPlugOutputSpecificData::ExtendedPlugInfoPlugOutputSpecificData() - : IBusData() - , m_nrOfOutputPlugs( 0 ) -{ -} - -ExtendedPlugInfoPlugOutputSpecificData::ExtendedPlugInfoPlugOutputSpecificData( const ExtendedPlugInfoPlugOutputSpecificData& rhs) - : IBusData() - , m_nrOfOutputPlugs( rhs.m_nrOfOutputPlugs ) -{ - for ( PlugAddressVector::const_iterator it = rhs.m_outputPlugAddresses.begin(); - it != rhs.m_outputPlugAddresses.end(); - ++it ) - { - m_outputPlugAddresses.push_back( ( *it )->clone() ); - } - -} - - -ExtendedPlugInfoPlugOutputSpecificData::~ExtendedPlugInfoPlugOutputSpecificData() -{ - for ( PlugAddressVector::iterator it = m_outputPlugAddresses.begin(); - it != m_outputPlugAddresses.end(); - ++it ) - { - delete *it; - } -} - -bool -ExtendedPlugInfoPlugOutputSpecificData::serialize( IOSSerialize& se ) -{ - se.write( m_nrOfOutputPlugs, "ExtendedPlugInfoPlugOutputSpecificData: number of output plugs" ); - for ( PlugAddressVector::const_iterator it = m_outputPlugAddresses.begin(); - it != m_outputPlugAddresses.end(); - ++it ) - { - ( *it )->serialize( se ); - } - - return true; -} - -bool -ExtendedPlugInfoPlugOutputSpecificData::deserialize( IISDeserialize& de ) -{ - de.read( &m_nrOfOutputPlugs ); - - for ( int i = 0; i < m_nrOfOutputPlugs; ++i ) - { - UnitPlugSpecificDataPlugAddress - unitPlug( UnitPlugSpecificDataPlugAddress::ePT_PCR, 0x00 ); - PlugAddressSpecificData* plugAddress - = new PlugAddressSpecificData( PlugAddressSpecificData::ePD_Output, - PlugAddressSpecificData::ePAM_Unit, - unitPlug ); - if ( !plugAddress->deserialize( de ) ) { - return false; - } - - m_outputPlugAddresses.push_back( plugAddress ); - } - - return true; -} - -ExtendedPlugInfoPlugOutputSpecificData::ExtendedPlugInfoPlugOutputSpecificData* -ExtendedPlugInfoPlugOutputSpecificData::clone() const -{ - return new ExtendedPlugInfoPlugOutputSpecificData( *this ); -} - -///////////////////////////////////////// -///////////////////////////////////////// -ExtendedPlugInfoClusterInfoSpecificData::ExtendedPlugInfoClusterInfoSpecificData() - : IBusData() - , m_clusterIndex( 0 ) - , m_portType( ePT_NoType ) - , m_stringLength( 0xff ) -{ -} - -ExtendedPlugInfoClusterInfoSpecificData::~ExtendedPlugInfoClusterInfoSpecificData() -{ -} - -bool -ExtendedPlugInfoClusterInfoSpecificData::serialize( IOSSerialize& se ) -{ - se.write( m_clusterIndex, - "ExtendedPlugInfoClusterInfoSpecificData: cluster index" ); - se.write( m_portType, - "ExtendedPlugInfoClusterInfoSpecificData: port type" ); - se.write( m_stringLength, - "ExtendedPlugInfoClusterInfoSpecificData: string length" ); - for ( unsigned int i = 0; i < m_clusterName.length(); ++i ) { - se.write( static_cast( m_clusterName[i] ), - "ExtendedPlugInfoClusterInfoSpecificData: char" ); - } - - return true; -} - -bool -ExtendedPlugInfoClusterInfoSpecificData::deserialize( IISDeserialize& de ) -{ - - de.read( &m_clusterIndex ); - de.read( &m_portType ); - de.read( &m_stringLength ); - - char* name = new char[m_stringLength+1]; - for ( int i = 0; i < m_stringLength; ++i ) { - byte_t c; - de.read( &c ); - // \todo do correct encoding - if ( c == '&' ) { - c = '+'; - } - name[i] = c; - } - name[m_stringLength] = '\0'; - m_clusterName = name; - delete[] name; - - return true; -} - -ExtendedPlugInfoClusterInfoSpecificData::ExtendedPlugInfoClusterInfoSpecificData* -ExtendedPlugInfoClusterInfoSpecificData::clone() const -{ - return new ExtendedPlugInfoClusterInfoSpecificData( *this ); -} - -const char* extendedPlugInfoPortTypeStrings[] = -{ - "Speaker", - "Headphone", - "Microphone", - "Line", - "SPDIF", - "ADAT", - "TDIF", - "MADI", - "Analog", - "Digital", - "MIDI", -}; - -const char* extendedPlugInfoClusterInfoPortTypeToString( port_type_t portType ) -{ - if ( portType > ( ( sizeof( extendedPlugInfoPortTypeStrings ) ) - / ( sizeof( extendedPlugInfoPortTypeStrings[0] ) ) ) ) { - return "Unknown"; - } else { - return extendedPlugInfoPortTypeStrings[portType]; - } -} - -///////////////////////////////////////// -///////////////////////////////////////// -///////////////////////////////////////// -///////////////////////////////////////// - -ExtendedPlugInfoInfoType::ExtendedPlugInfoInfoType(EInfoType eInfoType) - : IBusData() - , m_infoType( eInfoType ) - , m_plugType( 0 ) - , m_plugName( 0 ) - , m_plugNrOfChns( 0 ) - , m_plugChannelPosition( 0 ) - , m_plugChannelName( 0 ) - , m_plugInput( 0 ) - , m_plugOutput( 0 ) - , m_plugClusterInfo( 0 ) -{ -} - -ExtendedPlugInfoInfoType::ExtendedPlugInfoInfoType( const ExtendedPlugInfoInfoType& rhs ) - : IBusData() - , m_infoType( rhs.m_infoType ) - , m_plugType( 0 ) - , m_plugName( 0 ) - , m_plugNrOfChns( 0 ) - , m_plugChannelPosition( 0 ) - , m_plugChannelName( 0 ) - , m_plugInput( 0 ) - , m_plugOutput( 0 ) - , m_plugClusterInfo( 0 ) -{ - switch( m_infoType ) { - case eIT_PlugType: - m_plugType = - new ExtendedPlugInfoPlugTypeSpecificData( *rhs.m_plugType ); - break; - case eIT_PlugName: - m_plugName = - new ExtendedPlugInfoPlugNameSpecificData( *rhs.m_plugName ); - break; - case eIT_NoOfChannels: - m_plugNrOfChns = - new ExtendedPlugInfoPlugNumberOfChannelsSpecificData( *rhs.m_plugNrOfChns ); - break; - case eIT_ChannelPosition: - m_plugChannelPosition = - new ExtendedPlugInfoPlugChannelPositionSpecificData( *rhs.m_plugChannelPosition ); - break; - case eIT_ChannelName: - m_plugChannelName = - new ExtendedPlugInfoPlugChannelNameSpecificData( *rhs.m_plugChannelName ); - break; - case eIT_PlugInput: - m_plugInput = - new ExtendedPlugInfoPlugInputSpecificData( *rhs.m_plugInput ); - break; - case eIT_PlugOutput: - m_plugOutput = - new ExtendedPlugInfoPlugOutputSpecificData( *rhs.m_plugOutput ); - break; - case eIT_ClusterInfo: - m_plugClusterInfo = - new ExtendedPlugInfoClusterInfoSpecificData( *rhs.m_plugClusterInfo ); - break; - } -} - -ExtendedPlugInfoInfoType::~ExtendedPlugInfoInfoType() -{ - delete( m_plugType ); - delete( m_plugName ); - delete( m_plugNrOfChns ); - delete( m_plugChannelPosition ); - delete( m_plugChannelName ); - delete( m_plugInput ); - delete( m_plugOutput ); - delete( m_plugClusterInfo ); - } - -bool -ExtendedPlugInfoInfoType::initialize() -{ - switch ( m_infoType ) { - case eIT_PlugType: - m_plugType = new ExtendedPlugInfoPlugTypeSpecificData; - break; - case eIT_PlugName: - m_plugName = new ExtendedPlugInfoPlugNameSpecificData; - break; - case eIT_NoOfChannels: - m_plugNrOfChns = new ExtendedPlugInfoPlugNumberOfChannelsSpecificData; - break; - case eIT_ChannelPosition: - m_plugChannelPosition = new ExtendedPlugInfoPlugChannelPositionSpecificData; - break; - case eIT_ChannelName: - m_plugChannelName = new ExtendedPlugInfoPlugChannelNameSpecificData; - break; - case eIT_PlugInput: - m_plugInput = new ExtendedPlugInfoPlugInputSpecificData; - break; - case eIT_PlugOutput: - m_plugOutput = new ExtendedPlugInfoPlugOutputSpecificData; - break; - case eIT_ClusterInfo: - m_plugClusterInfo = new ExtendedPlugInfoClusterInfoSpecificData; - break; - default: - return false; - } - - return true; -} - -bool -ExtendedPlugInfoInfoType::serialize( IOSSerialize& se ) -{ - // XXX \todo improve IOSSerialize::write interface - char* buf; - asprintf( &buf, "ExtendedPlugInfoInfoType infoType (%s)", - extendedPlugInfoInfoTypeToString( m_infoType ) ); - se.write( m_infoType, buf ); - - free(buf); - - switch ( m_infoType ) { - case eIT_PlugType: - if ( m_plugType ) { - m_plugType->serialize( se ); - } - break; - case eIT_PlugName: - if ( m_plugName ) { - m_plugName->serialize( se ); - } - break; - case eIT_NoOfChannels: - if ( m_plugNrOfChns ) { - m_plugNrOfChns->serialize( se ); - } - break; - case eIT_ChannelPosition: - if ( m_plugChannelPosition ) { - m_plugChannelPosition->serialize( se ); - } - break; - case eIT_ChannelName: - if ( m_plugChannelName ) { - m_plugChannelName->serialize( se ); - } - break; - case eIT_PlugInput: - if ( m_plugInput ) { - m_plugInput->serialize( se ); - } - break; - case eIT_PlugOutput: - if ( m_plugOutput ) { - m_plugOutput->serialize( se ); - } - break; - case eIT_ClusterInfo: - if ( m_plugClusterInfo ) { - m_plugClusterInfo->serialize( se ); - } - break; - default: - return false; - } - - return true; -} - -bool -ExtendedPlugInfoInfoType::deserialize( IISDeserialize& de ) -{ - bool status = false; - - de.read( &m_infoType ); - - switch ( m_infoType ) { - case eIT_PlugType: - if ( !m_plugType ) { - m_plugType = new ExtendedPlugInfoPlugTypeSpecificData; - } - status = m_plugType->deserialize( de ); - break; - case eIT_PlugName: - if ( !m_plugName ) { - m_plugName = new ExtendedPlugInfoPlugNameSpecificData; - } - status = m_plugName->deserialize( de ); - break; - case eIT_NoOfChannels: - if ( !m_plugNrOfChns ) { - m_plugNrOfChns = - new ExtendedPlugInfoPlugNumberOfChannelsSpecificData; - } - status = m_plugNrOfChns->deserialize( de ); - break; - case eIT_ChannelPosition: - if ( !m_plugChannelPosition ) { - m_plugChannelPosition = - new ExtendedPlugInfoPlugChannelPositionSpecificData; - } - status = m_plugChannelPosition->deserialize( de ); - break; - case eIT_ChannelName: - if ( !m_plugChannelName ) { - m_plugChannelName = - new ExtendedPlugInfoPlugChannelNameSpecificData; - } - status = m_plugChannelName->deserialize( de ); - break; - case eIT_PlugInput: - if ( !m_plugInput ) { - m_plugInput = new ExtendedPlugInfoPlugInputSpecificData; - } - status = m_plugInput->deserialize( de ); - break; - case eIT_PlugOutput: - if ( !m_plugOutput ) { - m_plugOutput = new ExtendedPlugInfoPlugOutputSpecificData; - } - status = m_plugOutput->deserialize( de ); - break; - case eIT_ClusterInfo: - if ( !m_plugClusterInfo ) { - m_plugClusterInfo = new ExtendedPlugInfoClusterInfoSpecificData; - } - status =m_plugClusterInfo->deserialize( de ); - break; - default: - return false; - } - - return status; -} - -ExtendedPlugInfoInfoType* -ExtendedPlugInfoInfoType::clone() const -{ - ExtendedPlugInfoInfoType* extPlugInfoInfoType - = new ExtendedPlugInfoInfoType( *this ); - extPlugInfoInfoType->initialize(); - return extPlugInfoInfoType; -} - -const char* extendedPlugInfoInfoTypeStrings[] = -{ - "PlugType", - "PlugName", - "NoOfChannels", - "ChannelPosition", - "ChannelName", - "PlugInput", - "PlugOutput", - "ClusterInfo", -}; - -const char* extendedPlugInfoInfoTypeToString( info_type_t infoType ) -{ - if ( infoType > ( ( sizeof( extendedPlugInfoInfoTypeStrings ) ) - / ( sizeof( extendedPlugInfoInfoTypeStrings[0] ) ) ) ) { - return "Unknown"; - } else { - return extendedPlugInfoInfoTypeStrings[infoType]; - } -} - - -////////////////////////////////////////////// - -ExtendedPlugInfoCmd::ExtendedPlugInfoCmd( Ieee1394Service& ieee1394service, - ESubFunction eSubFunction ) - : AVCCommand( ieee1394service, AVC1394_CMD_PLUG_INFO ) -{ - setSubFunction( eSubFunction ); - UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, 0x00 ); - m_plugAddress = new PlugAddress( PlugAddress::ePD_Output, - PlugAddress::ePAM_Unit, - unitPlugAddress ); - m_infoType = - new ExtendedPlugInfoInfoType( ExtendedPlugInfoInfoType::eIT_PlugType ); - m_infoType->initialize(); -} - -ExtendedPlugInfoCmd::ExtendedPlugInfoCmd( const ExtendedPlugInfoCmd& rhs ) - : AVCCommand( rhs ) -{ - m_subFunction = rhs.m_subFunction; - m_plugAddress = new PlugAddress( *rhs.m_plugAddress ); - m_infoType = new ExtendedPlugInfoInfoType( *rhs.m_infoType ); -} - -ExtendedPlugInfoCmd::~ExtendedPlugInfoCmd() -{ - delete m_plugAddress; - m_plugAddress = 0; - delete m_infoType; - m_infoType = 0; -} - -bool -ExtendedPlugInfoCmd::serialize( IOSSerialize& se ) -{ - bool status = false; - AVCCommand::serialize( se ); - se.write( m_subFunction, "ExtendedPlugInfoCmd subFunction" ); - status = m_plugAddress->serialize( se ); - status &= m_infoType->serialize( se ); - - return status; -} - -bool -ExtendedPlugInfoCmd::deserialize( IISDeserialize& de ) -{ - bool status = false; - AVCCommand::deserialize( de ); - de.read( &m_subFunction ); - status = m_plugAddress->deserialize( de ); - status &= m_infoType->deserialize( de ); - - return status; -} - -bool -ExtendedPlugInfoCmd::setPlugAddress( const PlugAddress& plugAddress ) -{ - delete m_plugAddress; - m_plugAddress = plugAddress.clone(); - return true; -} - -bool -ExtendedPlugInfoCmd::setSubFunction( ESubFunction subFunction ) -{ - m_subFunction = subFunction; - return true; -} - -bool -ExtendedPlugInfoCmd::setInfoType( const ExtendedPlugInfoInfoType& infoType ) -{ - delete m_infoType; - m_infoType = infoType.clone(); - return true; -} Index: trunk/libffado/src/libavc/avc_signal_source.h =================================================================== --- trunk/libffado/src/libavc/avc_signal_source.h (revision 445) +++ (revision ) @@ -1,101 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#ifndef AVCSIGNALSOURCE_H -#define AVCSIGNALSOURCE_H - -#include "avc_generic.h" -#include "avc_definitions.h" - -#include - -class SignalAddress: public IBusData -{ -public: - enum EPlugId { - ePI_AnyAvailableSerialBusPlug = 0x7e, - ePI_Invalid = 0xfe, - ePI_AnyAvailableExternalPlug = 0xff, - }; -}; - -class SignalUnitAddress: public SignalAddress -{ -public: - SignalUnitAddress(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual SignalUnitAddress* clone() const; - - byte_t m_plugId; -}; - -class SignalSubunitAddress: public SignalAddress -{ -public: - SignalSubunitAddress(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual SignalSubunitAddress* clone() const; - - byte_t m_subunitType; - byte_t m_subunitId; - byte_t m_plugId; -}; - -class SignalSourceCmd: public AVCCommand -{ -public: - SignalSourceCmd( Ieee1394Service& ieee1394service ); - virtual ~SignalSourceCmd(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - - virtual const char* getCmdName() const - { return "SignalSourceCmd"; } - - bool setSignalSource( SignalUnitAddress& signalAddress ); - bool setSignalSource( SignalSubunitAddress& signalAddress ); - bool setSignalDestination( SignalUnitAddress& signalAddress ); - bool setSignalDestination( SignalSubunitAddress& signalAddress ); - - SignalAddress* getSignalSource(); - SignalAddress* getSignalDestination(); - - // Control response - byte_t m_resultStatus; - - // Status response - byte_t m_outputStatus; - byte_t m_conv; - byte_t m_signalStatus; - - SignalAddress* m_signalSource; - SignalAddress* m_signalDestination; -}; - - -#endif // AVCSIGNALSOURCE_H Index: trunk/libffado/src/libavc/avc_function_block.h =================================================================== --- trunk/libffado/src/libavc/avc_function_block.h (revision 455) +++ (revision ) @@ -1,275 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#ifndef AVCFUNCTIONBLOCK_H -#define AVCFUNCTIONBLOCK_H - -#include "avc_extended_cmd_generic.h" -#include "avc_generic.h" - -#include -#include -using namespace std; - -class FunctionBlockFeatureVolume: public IBusData -{ -public: - FunctionBlockFeatureVolume(); - FunctionBlockFeatureVolume( const FunctionBlockFeatureVolume& rhs ); - virtual ~FunctionBlockFeatureVolume(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual FunctionBlockFeatureVolume* clone() const; - - control_data_length_t m_controlDataLength; - u_int16_t m_volume; -}; - -/////////////////////////////////////////// - -class FunctionBlockProcessingMixer: public IBusData -{ -public: - FunctionBlockProcessingMixer(); - FunctionBlockProcessingMixer( const FunctionBlockProcessingMixer& rhs ); - virtual ~FunctionBlockProcessingMixer(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual FunctionBlockProcessingMixer* clone() const; - - control_selector_t m_controlSelector; -}; - -/////////////////////////////////////////// - -class FunctionBlockProcessingEnhancedMixer: public IBusData -{ -public: - enum EStatusSelector { - eSS_ProgramableState = 0x00, - eSS_Level = 0x01, - }; - - FunctionBlockProcessingEnhancedMixer(); - FunctionBlockProcessingEnhancedMixer( - const FunctionBlockProcessingEnhancedMixer& rhs ); - virtual ~FunctionBlockProcessingEnhancedMixer(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual FunctionBlockProcessingEnhancedMixer* clone() const; - - control_selector_t m_controlSelector; - status_selector_t m_statusSelector; - control_data_ext_length_t m_controlDataLength; - vector m_ProgramableStateData; - vector m_LevelData; -}; - -/////////////////////////////////////////// -/////////////////////////////////////////// - -class FunctionBlockSelector: public IBusData -{ -// untested -public: - // Control selector encoding - enum EControlSelectorEncoding { - eCSE_Selector_Unknown = 0x00, - eCSE_Selector_Selector = 0x01, - }; - - FunctionBlockSelector(); - FunctionBlockSelector( const FunctionBlockSelector& rhs ); - virtual ~FunctionBlockSelector(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual FunctionBlockSelector* clone() const; - - selector_length_t m_selectorLength; - input_fb_plug_number_t m_inputFbPlugNumber; - control_selector_t m_controlSelector; -}; - -/////////////////////////////////////////// - -class FunctionBlockFeature: public IBusData -{ -// no complete implementation -public: - // Control selector encoding - enum EControlSelectorEncoding { - eCSE_Feature_Unknown = 0x00, - eCSE_Feature_Mute = 0x01, - eCSE_Feature_Volume = 0x02, - eCSE_Feature_LRBalance = 0x03, - eCSE_Feature_FRBalance = 0x04, - eCSE_Feature_Bass = 0x05, - eCSE_Feature_Mid = 0x06, - eCSE_Feature_Treble = 0x07, - eCSE_Feature_GEQ = 0x08, - eCSE_Feature_AGC = 0x09, - eCSE_Feature_Delay = 0x0a, - eCSE_Feature_BassBoost = 0x0b, - eCSE_Feature_Loudness = 0x0c, - }; - - FunctionBlockFeature(); - FunctionBlockFeature( const FunctionBlockFeature& rhs ); - virtual ~FunctionBlockFeature(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual FunctionBlockFeature* clone() const; - - selector_length_t m_selectorLength; - audio_channel_number_t m_audioChannelNumber; - control_selector_t m_controlSelector; - - FunctionBlockFeatureVolume* m_pVolume; -}; - -/////////////////////////////////////////// - -class FunctionBlockProcessing: public IBusData -{ -// no complete implementation -public: - // Function block selector - enum EProcessingTypeEncoding { - ePTE_Mixer = 0x01, - ePTE_Generic = 0x02, - ePTE_UpDown = 0x03, - ePTE_DolbyProLogic = 0x04, - ePTE_3dStereoExtender = 0x05, - ePTE_Reverberation = 0x06, - ePTE_Chorus = 0x07, - ePTE_DynamicRangeCompression = 0x08, - }; - - // Control selector encoding - enum EControlSelectorEncoding { - eCSE_Processing_Unknown = 0x00, - eCSE_Processing_Enable = 0x01, - eCSE_Processing_Mode = 0x02, - eCSE_Processing_Mixer = 0x03, - eCSE_Processing_EnhancedMixer = 0xf1, - - // lots of definitions missing - - }; - - FunctionBlockProcessing(); - FunctionBlockProcessing( const FunctionBlockProcessing& rhs ); - virtual ~FunctionBlockProcessing(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual FunctionBlockProcessing* clone() const; - - selector_length_t m_selectorLength; - input_fb_plug_number_t m_fbInputPlugNumber; - input_audio_channel_number_t m_inputAudioChannelNumber; - output_audio_channel_number_t m_outputAudioChannelNumber; - - FunctionBlockProcessingMixer* m_pMixer; - FunctionBlockProcessingEnhancedMixer* m_pEnhancedMixer; -}; - -/////////////////////////////////////////// - -class FunctionBlockCodec: public IBusData -{ -// dummy implementation -public: - // CODEC type endcoding - enum ECodecTypeEncoding { - eCTE_Unknown = 0x00, - eCTE_Ac3Decoder = 0x01, - eCTE_MpegDecoder = 0x02, - eCTE_DtsDecoder = 0x03, - }; - - FunctionBlockCodec(); - FunctionBlockCodec( const FunctionBlockCodec& rhs ); - virtual ~FunctionBlockCodec(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual FunctionBlockCodec* clone() const; -}; - -/////////////////////////////////////////// -/////////////////////////////////////////// - -#define AVC1394_FUNCTION_BLOCK_CMD 0xB8 - -class FunctionBlockCmd: public AVCCommand -{ -public: - enum EFunctionBlockType { - eFBT_Selector = 0x80, - eFBT_Feature = 0x81, - eFBT_Processing = 0x82, - eFBT_Codec = 0x83, - }; - - enum EControlAttribute { - eCA_Resolution = 0x01, - eCA_Minimum = 0x02, - eCA_Maximum = 0x03, - eCA_Default = 0x04, - eCA_Duration = 0x08, - eCA_Current = 0x10, - eCA_Move = 0x18, - eCA_Delta = 0x19, - }; - - FunctionBlockCmd( Ieee1394Service& ieee1394service, - EFunctionBlockType eType, - function_block_id_t id, - EControlAttribute eCtrlAttrib ); - FunctionBlockCmd( const FunctionBlockCmd& rhs ); - virtual ~FunctionBlockCmd(); - - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); - virtual FunctionBlockCmd* clone() const; - - virtual const char* getCmdName() const - { return "FunctionBlockCmd"; } - - function_block_type_t m_functionBlockType; - function_block_id_t m_functionBlockId; - control_attribute_t m_controlAttribute; - - FunctionBlockSelector* m_pFBSelector; - FunctionBlockFeature* m_pFBFeature; - FunctionBlockProcessing* m_pFBProcessing; - FunctionBlockCodec* m_pFBCodec; -}; - -#endif Index: trunk/libffado/src/libavc/avc_subunit_info.cpp =================================================================== --- trunk/libffado/src/libavc/avc_subunit_info.cpp (revision 445) +++ (revision ) @@ -1,97 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "avc_subunit_info.h" -#include "avc_serialize.h" -#include "libieee1394/ieee1394service.h" - -#include -#include - -using namespace std; - -SubUnitInfoCmd::SubUnitInfoCmd( Ieee1394Service& ieee1349service ) - : AVCCommand( ieee1349service, AVC1394_CMD_SUBUNIT_INFO ) -{ - clear(); -} - -bool -SubUnitInfoCmd::clear() -{ - m_page = 0xff; - m_extension_code = 0x7; - for ( int i = 0; i < eMaxSubunitsPerPage; ++i ) { - m_table[i].m_subunit_type = 0xff; - m_table[i].m_max_subunit_id = 0xff; - } - m_nrOfValidEntries = 0; - return true; -} - - -SubUnitInfoCmd::~SubUnitInfoCmd() -{ -} - -bool -SubUnitInfoCmd::serialize( IOSSerialize& se ) -{ - AVCCommand::serialize( se ); - - byte_t operand = 0; - operand = (( m_page & 0x7 ) << 4 ) | ( m_extension_code & 0x7 ); - se.write( operand, "SubUnitInfoCmd page and extension_code" ); - - for ( int i = 0; i < eMaxSubunitsPerPage; ++i ) { - operand = ( m_table[i].m_subunit_type << 3 ) - | ( m_table[i].m_max_subunit_id & 0x7 ); - se.write( operand, "SubUnitInfoCmd subunit_type and max_subunit_ID" ); - } - - return true; -} - -bool -SubUnitInfoCmd::deserialize( IISDeserialize& de ) -{ - AVCCommand::deserialize( de ); - - byte_t operand; - de.read( &operand ); - m_page = ( operand >> 4 ) & 0x7; - m_extension_code = operand & 0x7; - - m_nrOfValidEntries = 0; - for ( int i = 0; i < eMaxSubunitsPerPage; ++i ) { - de.read( &operand ); - m_table[i].m_subunit_type = operand >> 3; - m_table[i].m_max_subunit_id = operand & 0x7; - - if ( operand != 0xff ) { - m_nrOfValidEntries++; - } - } - - return true; -} Index: trunk/libffado/src/ffado.cpp =================================================================== --- trunk/libffado/src/ffado.cpp (revision 454) +++ trunk/libffado/src/ffado.cpp (revision 554) @@ -30,7 +30,5 @@ #include "fbtypes.h" #include "devicemanager.h" -#include "iavdevice.h" - -#include "libavc/avc_generic.h" +#include "ffadodevice.h" #include @@ -133,7 +131,7 @@ ffado_set_samplerate( ffado_handle_t ffado_handle, int node_id, int samplerate ) { - IAvDevice* avDevice = ffado_handle->m_deviceManager->getAvDevice( node_id ); + FFADODevice* avDevice = ffado_handle->m_deviceManager->getAvDevice( node_id ); if ( avDevice ) { - if ( avDevice->setSamplingFrequency( parseSampleRate( samplerate ) ) ) { + if ( avDevice->setSamplingFrequency( samplerate ) ) { return ffado_handle->m_deviceManager->discover()? 0 : -1; } @@ -142,6 +140,8 @@ } +#warning this should be cleaned up +#include "libavc/general/avc_generic.h" void ffado_sleep_after_avc_command( int time ) { - AVCCommand::setSleepAfterAVCCommand( time ); + AVC::AVCCommand::setSleepAfterAVCCommand( time ); } Index: trunk/libffado/src/dice/dice_avdevice.h =================================================================== --- trunk/libffado/src/dice/dice_avdevice.h (revision 516) +++ trunk/libffado/src/dice/dice_avdevice.h (revision 554) @@ -25,5 +25,5 @@ #define DICEDEVICE_H -#include "iavdevice.h" +#include "ffadodevice.h" #include "debugmodule/debugmodule.h" @@ -52,5 +52,5 @@ }; -class DiceAvDevice : public IAvDevice { +class DiceAvDevice : public FFADODevice { private: class DiceNotifier; @@ -67,5 +67,5 @@ virtual void showDevice(); - virtual bool setSamplingFrequency( ESamplingFrequency samplingFrequency ); + virtual bool setSamplingFrequency( int samplingFrequency ); virtual int getSamplingFrequency( ); @@ -189,5 +189,4 @@ DiceAvDevice *m_dicedevice; }; - }; Index: trunk/libffado/src/dice/dice_avdevice.cpp =================================================================== --- trunk/libffado/src/dice/dice_avdevice.cpp (revision 479) +++ trunk/libffado/src/dice/dice_avdevice.cpp (revision 554) @@ -54,5 +54,5 @@ Ieee1394Service& ieee1394service, int nodeId ) - : IAvDevice( configRom, ieee1394service, nodeId ) + : FFADODevice( configRom, ieee1394service, nodeId ) , m_model( NULL ) , m_global_reg_offset (0xFFFFFFFFLU) @@ -143,5 +143,5 @@ int DiceAvDevice::getSamplingFrequency( ) { - ESamplingFrequency samplingFrequency; + int samplingFrequency; fb_quadlet_t clockreg; @@ -154,19 +154,19 @@ switch (clockreg) { - case DICE_RATE_32K: samplingFrequency = eSF_32000Hz; break; - case DICE_RATE_44K1: samplingFrequency = eSF_44100Hz; break; - case DICE_RATE_48K: samplingFrequency = eSF_48000Hz; break; - case DICE_RATE_88K2: samplingFrequency = eSF_88200Hz; break; - case DICE_RATE_96K: samplingFrequency = eSF_96000Hz; break; - case DICE_RATE_176K4: samplingFrequency = eSF_176400Hz; break; - case DICE_RATE_192K: samplingFrequency = eSF_192000Hz; break; - case DICE_RATE_ANY_LOW: samplingFrequency = eSF_AnyLow; break; - case DICE_RATE_ANY_MID: samplingFrequency = eSF_AnyMid; break; - case DICE_RATE_ANY_HIGH: samplingFrequency = eSF_AnyHigh; break; - case DICE_RATE_NONE: samplingFrequency = eSF_None; break; - default: samplingFrequency = eSF_DontCare; break; - } - - return convertESamplingFrequency(samplingFrequency); + case DICE_RATE_32K: samplingFrequency = 32000; break; + case DICE_RATE_44K1: samplingFrequency = 44100; break; + case DICE_RATE_48K: samplingFrequency = 48000; break; + case DICE_RATE_88K2: samplingFrequency = 88200; break; + case DICE_RATE_96K: samplingFrequency = 96000; break; + case DICE_RATE_176K4: samplingFrequency = 176400; break; + case DICE_RATE_192K: samplingFrequency = 192000; break; + case DICE_RATE_ANY_LOW: samplingFrequency = 0; break; + case DICE_RATE_ANY_MID: samplingFrequency = 0; break; + case DICE_RATE_ANY_HIGH: samplingFrequency = 0; break; + case DICE_RATE_NONE: samplingFrequency = 0; break; + default: samplingFrequency = 0; break; + } + + return samplingFrequency; } @@ -178,8 +178,8 @@ bool -DiceAvDevice::setSamplingFrequency( ESamplingFrequency samplingFrequency ) +DiceAvDevice::setSamplingFrequency( int samplingFrequency ) { debugOutput(DEBUG_LEVEL_VERBOSE, "Setting sample rate: %d\n", - convertESamplingFrequency(samplingFrequency)); + (samplingFrequency)); bool supported=false; @@ -188,9 +188,9 @@ switch ( samplingFrequency ) { default: - case eSF_22050Hz: - case eSF_24000Hz: + case 22050: + case 24000: supported=false; break; - case eSF_32000Hz: + case 32000: supported=maskedCheckNotZeroGlobalReg( DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, @@ -198,5 +198,5 @@ select=DICE_RATE_32K; break; - case eSF_44100Hz: + case 44100: supported=maskedCheckNotZeroGlobalReg( DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, @@ -204,5 +204,5 @@ select=DICE_RATE_44K1; break; - case eSF_48000Hz: + case 48000: supported=maskedCheckNotZeroGlobalReg( DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, @@ -210,5 +210,5 @@ select=DICE_RATE_48K; break; - case eSF_88200Hz: + case 88200: supported=maskedCheckNotZeroGlobalReg( DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, @@ -216,5 +216,5 @@ select=DICE_RATE_88K2; break; - case eSF_96000Hz: + case 96000: supported=maskedCheckNotZeroGlobalReg( DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, @@ -222,5 +222,5 @@ select=DICE_RATE_96K; break; - case eSF_176400Hz: + case 176400: supported=maskedCheckNotZeroGlobalReg( DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, @@ -228,5 +228,5 @@ select=DICE_RATE_176K4; break; - case eSF_192000Hz: + case 192000: supported=maskedCheckNotZeroGlobalReg( DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, @@ -237,5 +237,5 @@ if (!supported) { - debugWarning("Unsupported sample rate: %d\n", convertESamplingFrequency(samplingFrequency)); + debugWarning("Unsupported sample rate: %d\n", (samplingFrequency)); return false; } Index: trunk/libffado/src/bebob-sync.cpp =================================================================== --- trunk/libffado/src/bebob-sync.cpp (revision 445) +++ trunk/libffado/src/bebob-sync.cpp (revision 554) @@ -23,5 +23,5 @@ #include "devicemanager.h" -#include "iavdevice.h" +#include "ffadodevice.h" #include "bebob/bebob_avdevice.h" @@ -144,5 +144,5 @@ } - IAvDevice* pAvDevice = pDeviceManager->getAvDevice( node_id ); + FFADODevice* pAvDevice = pDeviceManager->getAvDevice( node_id ); if ( !pAvDevice ) { printf( "No recognized device found with id %d\n", node_id ); Index: trunk/libffado/src/libutil/TimestampedBuffer.h =================================================================== --- trunk/libffado/src/libutil/TimestampedBuffer.h (revision 512) +++ trunk/libffado/src/libutil/TimestampedBuffer.h (revision 554) @@ -1,4 +1,2 @@ -/* $Id$ */ - /* * FFADO Streaming API Index: trunk/libffado/src/genericavc/avc_avdevice.cpp =================================================================== --- trunk/libffado/src/genericavc/avc_avdevice.cpp (revision 548) +++ trunk/libffado/src/genericavc/avc_avdevice.cpp (revision 548) @@ -0,0 +1,599 @@ +/* + * Copyright (C) 2005-2007 by Pieter Palmers + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#warning Generic AV/C support is currently useless + +#include "genericavc/avc_avdevice.h" + +#include "libieee1394/configrom.h" +#include "libieee1394/ieee1394service.h" + +#include "libavc/avc_definitions.h" +#include "libavc/general/avc_plug_info.h" + +#include "debugmodule/debugmodule.h" + +#include +#include +#include +#include +#include +#include + +#include + +using namespace AVC; + +namespace GenericAVC { + +IMPL_DEBUG_MODULE( AvDevice, AvDevice, DEBUG_LEVEL_VERBOSE ); + +// to define the supported devices +static VendorModelEntry supportedDeviceList[] = +{ + {0x001486, 0x00000af2, "Echo", "AudioFire2"}, +}; + +AvDevice::AvDevice( std::auto_ptr< ConfigRom >( configRom ), + Ieee1394Service& ieee1394service, + int nodeId ) + : FFADODevice( configRom, ieee1394service, nodeId ) + , m_model( NULL ) + +{ + debugOutput( DEBUG_LEVEL_VERBOSE, "Created GenericAVC::AvDevice (NodeID %d)\n", + nodeId ); + addOption(Util::OptionContainer::Option("snoopMode",false)); +} + +AvDevice::~AvDevice() +{ + +} + +bool +AvDevice::probe( ConfigRom& configRom ) +{ + unsigned int vendorId = configRom.getNodeVendorId(); + unsigned int modelId = configRom.getModelId(); + + for ( unsigned int i = 0; + i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) ); + ++i ) + { + if ( ( supportedDeviceList[i].vendor_id == vendorId ) + && ( supportedDeviceList[i].model_id == modelId ) + ) + { + return true; + } + } + + return false; +} + +bool +AvDevice::discover() +{ + unsigned int vendorId = m_pConfigRom->getNodeVendorId(); + unsigned int modelId = m_pConfigRom->getModelId(); + + for ( unsigned int i = 0; + i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) ); + ++i ) + { + if ( ( supportedDeviceList[i].vendor_id == vendorId ) + && ( supportedDeviceList[i].model_id == modelId ) + ) + { + m_model = &(supportedDeviceList[i]); + } + } + + if (m_model == NULL) { + return false; + } + debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", + m_model->vendor_name, m_model->model_name); + + if ( !Unit::discover() ) { + debugError( "Could not discover unit\n" ); + return false; + } + + if((getAudioSubunit( 0 ) == NULL)) { + debugError( "Unit doesn't have an Audio subunit.\n"); + return false; + } + if((getMusicSubunit( 0 ) == NULL)) { + debugError( "Unit doesn't have a Music subunit.\n"); + return false; + } + + return true; +} + +void +AvDevice::setVerboseLevel(int l) +{ + m_pPlugManager->setVerboseLevel(l); + + FFADODevice::setVerboseLevel(l); + AVC::Unit::setVerboseLevel(l); +} + +int +AvDevice::getSamplingFrequency( ) { + AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 ); + if ( !inputPlug ) { + debugError( "setSampleRate: Could not retrieve iso input plug 0\n" ); + return false; + } + AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 ); + if ( !outputPlug ) { + debugError( "setSampleRate: Could not retrieve iso output plug 0\n" ); + return false; + } + + int samplerate_playback=inputPlug->getSampleRate(); + int samplerate_capture=outputPlug->getSampleRate(); + + if (samplerate_playback != samplerate_capture) { + debugWarning("Samplerates for capture and playback differ!\n"); + } + return samplerate_capture; +} + +bool +AvDevice::setSamplingFrequency( int s ) +{ + bool snoopMode=false; + if(!getOption("snoopMode", snoopMode)) { + debugWarning("Could not retrieve snoopMode parameter, defauling to false\n"); + } + + if(snoopMode) { + int current_sr=getSamplingFrequency(); + if (current_sr != s ) { + debugError("In snoop mode it is impossible to set the sample rate.\n"); + debugError("Please start the client with the correct setting.\n"); + return false; + } + return true; + } else { + AVC::Plug* plug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 ); + if ( !plug ) { + debugError( "setSampleRate: Could not retrieve iso input plug 0\n" ); + return false; + } + + if ( !plug->setSampleRate( s ) ) + { + debugError( "setSampleRate: Setting sample rate failed\n" ); + return false; + } + + plug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 ); + if ( !plug ) { + debugError( "setSampleRate: Could not retrieve iso output plug 0\n" ); + return false; + } + + if ( !plug->setSampleRate( s ) ) + { + debugError( "setSampleRate: Setting sample rate failed\n" ); + return false; + } + + debugOutput( DEBUG_LEVEL_VERBOSE, + "setSampleRate: Set sample rate to %d\n", + s ); + return true; + } + // not executable + return false; + +} + +bool +AvDevice::lock() { + bool snoopMode=false; + if(!getOption("snoopMode", snoopMode)) { + debugWarning("Could not retrieve snoopMode parameter, defauling to false\n"); + } + + if (snoopMode) { + // don't lock + } else { +// return Unit::reserve(4); + } + + return true; +} + +bool +AvDevice::unlock() { + bool snoopMode=false; + if(!getOption("snoopMode", snoopMode)) { + debugWarning("Could not retrieve snoopMode parameter, defauling to false\n"); + } + + if (snoopMode) { + // don't unlock + } else { +// return Unit::reserve(0); + } + return true; +} + +void +AvDevice::showDevice() +{ + debugOutput(DEBUG_LEVEL_VERBOSE, + "%s %s at node %d\n", m_model->vendor_name, m_model->model_name, + m_nodeId); + + m_pPlugManager->showPlugs(); + flushDebugOutput(); +} + +bool +AvDevice::prepare() { + bool snoopMode=false; + if(!getOption("snoopMode", snoopMode)) { + debugWarning("Could not retrieve snoopMode parameter, defauling to false\n"); + } + + /////////// + // get plugs + + AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 ); + if ( !inputPlug ) { + debugError( "setSampleRate: Could not retrieve iso input plug 0\n" ); + return false; + } + AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 ); + if ( !outputPlug ) { + debugError( "setSampleRate: Could not retrieve iso output plug 0\n" ); + return false; + } + + int samplerate=outputPlug->getSampleRate(); + + debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing receive processor...\n"); + // create & add streamprocessors + Streaming::StreamProcessor *p; + + p=new Streaming::AmdtpReceiveStreamProcessor( + get1394Service().getPort(), + samplerate, + outputPlug->getNrOfChannels()); + + if(!p->init()) { + debugFatal("Could not initialize receive processor!\n"); + delete p; + return false; + } + + if (!addPlugToProcessor(*outputPlug,p, + Streaming::Port::E_Capture)) { + debugFatal("Could not add plug to processor!\n"); + delete p; + return false; + } + + m_receiveProcessors.push_back(p); + + // do the transmit processor + debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing transmit processor%s...\n", + (snoopMode?" in snoop mode":"")); + if (snoopMode) { + // we are snooping, so this is receive too. + p=new Streaming::AmdtpReceiveStreamProcessor( + get1394Service().getPort(), + samplerate, + inputPlug->getNrOfChannels()); + } else { + p=new Streaming::AmdtpTransmitStreamProcessor( + get1394Service().getPort(), + samplerate, + inputPlug->getNrOfChannels()); + } + + if(!p->init()) { + debugFatal("Could not initialize transmit processor %s!\n", + (snoopMode?" in snoop mode":"")); + delete p; + return false; + } + + if (snoopMode) { + if (!addPlugToProcessor(*inputPlug,p, + Streaming::Port::E_Capture)) { + debugFatal("Could not add plug to processor!\n"); + return false; + } + } else { + if (!addPlugToProcessor(*inputPlug,p, + Streaming::Port::E_Playback)) { + debugFatal("Could not add plug to processor!\n"); + return false; + } + } + + // we put this SP into the transmit SP vector, + // no matter if we are in snoop mode or not + // this allows us to find out what direction + // a certain stream should have. + m_transmitProcessors.push_back(p); + + return true; +} + +bool +AvDevice::addPlugToProcessor( + AVC::Plug& plug, + Streaming::StreamProcessor *processor, + Streaming::AmdtpAudioPort::E_Direction direction) { + + std::string id=std::string("dev?"); + if(!getOption("id", id)) { + debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n"); + } + + Plug::ClusterInfoVector& clusterInfos = plug.getClusterInfos(); + for ( Plug::ClusterInfoVector::const_iterator it = clusterInfos.begin(); + it != clusterInfos.end(); + ++it ) + { + const Plug::ClusterInfo* clusterInfo = &( *it ); + + Plug::ChannelInfoVector channelInfos = clusterInfo->m_channelInfos; + for ( Plug::ChannelInfoVector::const_iterator it = channelInfos.begin(); + it != channelInfos.end(); + ++it ) + { + const Plug::ChannelInfo* channelInfo = &( *it ); + std::ostringstream portname; + + portname << id << "_" << channelInfo->m_name; + + Streaming::Port *p=NULL; + switch(clusterInfo->m_portType) { + case ExtendedPlugInfoClusterInfoSpecificData::ePT_Speaker: + case ExtendedPlugInfoClusterInfoSpecificData::ePT_Headphone: + case ExtendedPlugInfoClusterInfoSpecificData::ePT_Microphone: + case ExtendedPlugInfoClusterInfoSpecificData::ePT_Line: + case ExtendedPlugInfoClusterInfoSpecificData::ePT_Analog: + debugOutput(DEBUG_LEVEL_VERBOSE, " Adding audio channel %s (pos=0x%02X, loc=0x%02X)\n", + channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location); + p=new Streaming::AmdtpAudioPort( + portname.str(), + direction, + channelInfo->m_streamPosition, + channelInfo->m_location, + Streaming::AmdtpPortInfo::E_MBLA + ); + break; + + case ExtendedPlugInfoClusterInfoSpecificData::ePT_MIDI: + debugOutput(DEBUG_LEVEL_VERBOSE, " Adding MIDI channel %s (pos=0x%02X, loc=0x%02X)\n", + channelInfo->m_name.c_str(), channelInfo->m_streamPosition, processor->getPortCount(Streaming::Port::E_Midi)); + p=new Streaming::AmdtpMidiPort( + portname.str(), + direction, + channelInfo->m_streamPosition, + // Workaround for out-of-spec hardware + // should be: + // channelInfo->m_location, + // but now we renumber the midi channels' location as they + // are discovered + processor->getPortCount(Streaming::Port::E_Midi), + Streaming::AmdtpPortInfo::E_Midi + ); + + break; + case ExtendedPlugInfoClusterInfoSpecificData::ePT_SPDIF: + case ExtendedPlugInfoClusterInfoSpecificData::ePT_ADAT: + case ExtendedPlugInfoClusterInfoSpecificData::ePT_TDIF: + case ExtendedPlugInfoClusterInfoSpecificData::ePT_MADI: + case ExtendedPlugInfoClusterInfoSpecificData::ePT_Digital: + debugOutput(DEBUG_LEVEL_VERBOSE, " Adding digital audio channel %s (pos=0x%02X, loc=0x%02X)\n", + channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location); + p=new Streaming::AmdtpAudioPort( + portname.str(), + direction, + channelInfo->m_streamPosition, + channelInfo->m_location, + Streaming::AmdtpPortInfo::E_MBLA + ); + break; + + case ExtendedPlugInfoClusterInfoSpecificData::ePT_NoType: + default: + // unsupported + break; + } + + if (!p) { + debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str()); + } else { + + if (!processor->addPort(p)) { + debugWarning("Could not register port with stream processor\n"); + return false; + } + } + } + } + return true; +} + +int +AvDevice::getStreamCount() { + return m_receiveProcessors.size() + m_transmitProcessors.size(); +} + +Streaming::StreamProcessor * +AvDevice::getStreamProcessorByIndex(int i) { + + if (i<(int)m_receiveProcessors.size()) { + return m_receiveProcessors.at(i); + } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) { + return m_transmitProcessors.at(i-m_receiveProcessors.size()); + } + + return NULL; +} + +bool +AvDevice::startStreamByIndex(int i) { + int iso_channel=-1; + bool snoopMode=false; + if(!getOption("snoopMode", snoopMode)) { + debugWarning("Could not retrieve snoopMode parameter, defauling to false\n"); + } + + if (i<(int)m_receiveProcessors.size()) { + int n=i; + Streaming::StreamProcessor *p=m_receiveProcessors.at(n); + + if(snoopMode) { // a stream from the device to another host + // FIXME: put this into a decent framework! + // we should check the oPCR[n] on the device + struct iec61883_oPCR opcr; + if (iec61883_get_oPCRX( + get1394Service().getHandle(), + m_pConfigRom->getNodeId() | 0xffc0, + (quadlet_t *)&opcr, + n)) { + + debugWarning("Error getting the channel for SP %d\n",i); + return false; + } + + iso_channel=opcr.channel; + } else { + iso_channel=get1394Service().allocateIsoChannelCMP( + m_pConfigRom->getNodeId() | 0xffc0, n, + get1394Service().getLocalNodeId()| 0xffc0, -1); + } + if (iso_channel<0) { + debugError("Could not allocate ISO channel for SP %d\n",i); + return false; + } + + debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel); + + p->setChannel(iso_channel); + return true; + + } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) { + int n=i-m_receiveProcessors.size(); + Streaming::StreamProcessor *p=m_transmitProcessors.at(n); + + if(snoopMode) { // a stream from another host to the device + // FIXME: put this into a decent framework! + // we should check the iPCR[n] on the device + struct iec61883_iPCR ipcr; + if (iec61883_get_iPCRX( + get1394Service().getHandle(), + m_pConfigRom->getNodeId() | 0xffc0, + (quadlet_t *)&ipcr, + n)) { + + debugWarning("Error getting the channel for SP %d\n",i); + return false; + } + + iso_channel=ipcr.channel; + + } else { + iso_channel=get1394Service().allocateIsoChannelCMP( + get1394Service().getLocalNodeId()| 0xffc0, -1, + m_pConfigRom->getNodeId() | 0xffc0, n); + } + + if (iso_channel<0) { + debugError("Could not allocate ISO channel for SP %d\n",i); + return false; + } + + debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel); + + p->setChannel(iso_channel); + return true; + } + + debugError("SP index %d out of range!\n",i); + return false; +} + +bool +AvDevice::stopStreamByIndex(int i) { + bool snoopMode=false; + if(!getOption("snoopMode", snoopMode)) { + debugWarning("Could not retrieve snoopMode parameter, defauling to false\n"); + } + + if (i<(int)m_receiveProcessors.size()) { + int n=i; + Streaming::StreamProcessor *p=m_receiveProcessors.at(n); + + if(snoopMode) { + + } else { + // deallocate ISO channel + if(!get1394Service().freeIsoChannel(p->getChannel())) { + debugError("Could not deallocate iso channel for SP %d\n",i); + return false; + } + } + p->setChannel(-1); + + return true; + + } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) { + int n=i-m_receiveProcessors.size(); + Streaming::StreamProcessor *p=m_transmitProcessors.at(n); + + if(snoopMode) { + + } else { + // deallocate ISO channel + if(!get1394Service().freeIsoChannel(p->getChannel())) { + debugError("Could not deallocate iso channel for SP %d\n",i); + return false; + } + } + p->setChannel(-1); + + return true; + } + + debugError("SP index %d out of range!\n",i); + return false; +} + +} Index: trunk/libffado/src/genericavc/avc_avdevice.h =================================================================== --- trunk/libffado/src/genericavc/avc_avdevice.h (revision 548) +++ trunk/libffado/src/genericavc/avc_avdevice.h (revision 548) @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2005-2007 by Pieter Palmers + * Copyright (C) 2005-2007 by Daniel Wagner + * + * This file is part of FFADO + * FFADO = Free Firewire (pro-)audio drivers for linux + * + * FFADO is based upon FreeBoB. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef GENERICAVC_AVDEVICE_H +#define GENERICAVC_AVDEVICE_H + +#include "ffadodevice.h" + +#include "debugmodule/debugmodule.h" + +#include "libavc/avc_definitions.h" +#include "libavc/general/avc_unit.h" +#include "libavc/general/avc_subunit.h" +#include "libavc/general/avc_plug.h" + +#include "libstreaming/AmdtpStreamProcessor.h" +#include "libstreaming/AmdtpPort.h" +#include "libstreaming/AmdtpPortInfo.h" + +class ConfigRom; +class Ieee1394Service; + +namespace GenericAVC { + +// struct to define the supported devices +struct VendorModelEntry { + unsigned int vendor_id; + unsigned int model_id; + char *vendor_name; + char *model_name; +}; + +class AvDevice : public FFADODevice, public AVC::Unit { +public: + AvDevice( std::auto_ptr( configRom ), + Ieee1394Service& ieee1394Service, + int nodeId ); + virtual ~AvDevice(); + + static bool probe( ConfigRom& configRom ); + virtual bool discover(); + + virtual void setVerboseLevel(int l); + virtual void showDevice(); + + virtual bool setSamplingFrequency( int ); + virtual int getSamplingFrequency( ); + + virtual int getStreamCount(); + virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i); + + virtual bool prepare(); + virtual bool lock(); + virtual bool unlock(); + + virtual bool startStreamByIndex(int i); + virtual bool stopStreamByIndex(int i); + + // redefinition to resolve ambiguity + virtual Ieee1394Service& get1394Service() + { return FFADODevice::get1394Service(); }; + virtual ConfigRom& getConfigRom() const + { return FFADODevice::getConfigRom(); }; + +protected: + virtual bool addPlugToProcessor( AVC::Plug& plug, Streaming::StreamProcessor *processor, + Streaming::AmdtpAudioPort::E_Direction direction); +/* bool setSamplingFrequencyPlug( AVC::Plug& plug, + AVC::Plug::EPlugDirection direction, + AVC::ESamplingFrequency samplingFrequency );*/ + + struct VendorModelEntry *m_model; + + // streaming stuff + typedef std::vector< Streaming::StreamProcessor * > StreamProcessorVector; + StreamProcessorVector m_receiveProcessors; + StreamProcessorVector m_transmitProcessors; + + DECLARE_DEBUG_MODULE; +}; + +} + +#endif //GENERICAVC_AVDEVICE_H Index: trunk/libffado/src/ffado_streaming.cpp =================================================================== --- trunk/libffado/src/ffado_streaming.cpp (revision 494) +++ trunk/libffado/src/ffado_streaming.cpp (revision 554) @@ -28,5 +28,5 @@ #include "../libffado/ffado.h" #include "devicemanager.h" -#include "iavdevice.h" +#include "ffadodevice.h" #include "libstreaming/StreamProcessorManager.h" @@ -139,5 +139,5 @@ // add the stream processors of the devices to the managers for(i=0;im_deviceManager->getAvDeviceCount();i++) { - IAvDevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); + FFADODevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); assert(device); @@ -154,10 +154,10 @@ // Set the device's sampling rate to that requested // FIXME: does this really belong here? If so we need to handle errors. - if (!device->setSamplingFrequency(parseSampleRate(dev->options.sample_rate))) { + if (!device->setSamplingFrequency(dev->options.sample_rate)) { debugOutput(DEBUG_LEVEL_VERBOSE, " => Retry setting samplerate to %d for (%p)\n", dev->options.sample_rate, device); // try again: - if (!device->setSamplingFrequency(parseSampleRate(dev->options.sample_rate))) { + if (!device->setSamplingFrequency(dev->options.sample_rate)) { delete dev->processorManager; delete dev->m_deviceManager; @@ -211,5 +211,5 @@ // iterate over the found devices for(i=0;im_deviceManager->getAvDeviceCount();i++) { - IAvDevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); + FFADODevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); assert(device); @@ -236,5 +236,5 @@ // add the stream processors of the devices to the managers for(i=0;im_deviceManager->getAvDeviceCount();i++) { - IAvDevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); + FFADODevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); assert(device); @@ -272,5 +272,5 @@ // add the stream processors of the devices to the managers for(i=0;im_deviceManager->getAvDeviceCount();i++) { - IAvDevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); + FFADODevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); assert(device); Index: trunk/libffado/src/bebob/bebob_functionblock.h =================================================================== --- trunk/libffado/src/bebob/bebob_functionblock.h (revision 455) +++ trunk/libffado/src/bebob/bebob_functionblock.h (revision 554) @@ -28,9 +28,13 @@ #include "libavc/avc_definitions.h" +// #include "libavc/general/avc_subunit.h" + #include "debugmodule/debugmodule.h" +namespace AVC { + class Subunit; +} + namespace BeBoB { - -class AvDeviceSubunit; class FunctionBlock { @@ -50,11 +54,11 @@ }; - FunctionBlock( AvDeviceSubunit& subunit, - function_block_type_t type, - function_block_type_t subtype, - function_block_id_t id, + FunctionBlock( AVC::Subunit& subunit, + AVC::function_block_type_t type, + AVC::function_block_type_t subtype, + AVC::function_block_id_t id, ESpecialPurpose purpose, - no_of_input_plugs_t nrOfInputPlugs, - no_of_output_plugs_t nrOfOutputPlugs, + AVC::no_of_input_plugs_t nrOfInputPlugs, + AVC::no_of_output_plugs_t nrOfOutputPlugs, int verbose ); FunctionBlock( const FunctionBlock& rhs ); @@ -67,27 +71,27 @@ virtual const char* getName() = 0; - function_block_type_t getType() {return m_type;}; - function_block_type_t getSubtype() {return m_subtype;}; - function_block_id_t getId() {return m_id;}; + AVC::function_block_type_t getType() {return m_type;}; + AVC::function_block_type_t getSubtype() {return m_subtype;}; + AVC::function_block_id_t getId() {return m_id;}; bool serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const; static FunctionBlock* deserialize( Glib::ustring basePath, Util::IODeserialize& deser, - AvDevice& avDevice, - AvDeviceSubunit& subunit); -protected: - bool discoverPlugs( AvPlug::EAvPlugDirection plugDirection, - plug_id_t plugMaxId ); - -protected: - AvDeviceSubunit* m_subunit; - function_block_type_t m_type; - function_block_type_t m_subtype; - function_block_id_t m_id; + AVC::Unit& unit, + AVC::Subunit& subunit); +protected: + bool discoverPlugs( AVC::Plug::EPlugDirection plugDirection, + AVC::plug_id_t plugMaxId ); + +protected: + AVC::Subunit* m_subunit; + AVC::function_block_type_t m_type; + AVC::function_block_type_t m_subtype; + AVC::function_block_id_t m_id; ESpecialPurpose m_purpose; - no_of_input_plugs_t m_nrOfInputPlugs; - no_of_output_plugs_t m_nrOfOutputPlugs; + AVC::no_of_input_plugs_t m_nrOfInputPlugs; + AVC::no_of_output_plugs_t m_nrOfOutputPlugs; int m_verbose; - AvPlugVector m_plugs; + AVC::PlugVector m_plugs; DECLARE_DEBUG_MODULE; @@ -102,9 +106,9 @@ { public: - FunctionBlockSelector(AvDeviceSubunit& subunit, - function_block_id_t id, + FunctionBlockSelector(AVC::Subunit& subunit, + AVC::function_block_id_t id, ESpecialPurpose purpose, - no_of_input_plugs_t nrOfInputPlugs, - no_of_output_plugs_t nrOfOutputPlugs, + AVC::no_of_input_plugs_t nrOfInputPlugs, + AVC::no_of_output_plugs_t nrOfOutputPlugs, int verbose); FunctionBlockSelector( const FunctionBlockSelector& rhs ); @@ -127,9 +131,9 @@ { public: - FunctionBlockFeature(AvDeviceSubunit& subunit, - function_block_id_t id, + FunctionBlockFeature(AVC::Subunit& subunit, + AVC::function_block_id_t id, ESpecialPurpose purpose, - no_of_input_plugs_t nrOfInputPlugs, - no_of_output_plugs_t nrOfOutputPlugs, + AVC::no_of_input_plugs_t nrOfInputPlugs, + AVC::no_of_output_plugs_t nrOfOutputPlugs, int verbose); FunctionBlockFeature( const FunctionBlockFeature& rhs ); @@ -169,9 +173,9 @@ { public: - FunctionBlockEnhancedMixer( AvDeviceSubunit& subunit, - function_block_id_t id, + FunctionBlockEnhancedMixer( AVC::Subunit& subunit, + AVC::function_block_id_t id, ESpecialPurpose purpose, - no_of_input_plugs_t nrOfInputPlugs, - no_of_output_plugs_t nrOfOutputPlugs, + AVC::no_of_input_plugs_t nrOfInputPlugs, + AVC::no_of_output_plugs_t nrOfOutputPlugs, int verbose ); FunctionBlockEnhancedMixer(); @@ -194,9 +198,9 @@ { public: - FunctionBlockProcessing( AvDeviceSubunit& subunit, - function_block_id_t id, + FunctionBlockProcessing( AVC::Subunit& subunit, + AVC::function_block_id_t id, ESpecialPurpose purpose, - no_of_input_plugs_t nrOfInputPlugs, - no_of_output_plugs_t nrOfOutputPlugs, + AVC::no_of_input_plugs_t nrOfInputPlugs, + AVC::no_of_output_plugs_t nrOfOutputPlugs, int verbose ); FunctionBlockProcessing( const FunctionBlockProcessing& rhs ); @@ -219,9 +223,9 @@ { public: - FunctionBlockCodec(AvDeviceSubunit& subunit, - function_block_id_t id, + FunctionBlockCodec(AVC::Subunit& subunit, + AVC::function_block_id_t id, ESpecialPurpose purpose, - no_of_input_plugs_t nrOfInputPlugs, - no_of_output_plugs_t nrOfOutputPlugs, + AVC::no_of_input_plugs_t nrOfInputPlugs, + AVC::no_of_output_plugs_t nrOfOutputPlugs, int verbose); FunctionBlockCodec( const FunctionBlockCodec& rhs ); Index: trunk/libffado/src/bebob/bebob_dl_codes.cpp =================================================================== --- trunk/libffado/src/bebob/bebob_dl_codes.cpp (revision 445) +++ trunk/libffado/src/bebob/bebob_dl_codes.cpp (revision 554) @@ -24,4 +24,6 @@ #include "bebob/bebob_dl_codes.h" #include "bebob/bebob_dl_bcd.h" + +using namespace AVC; unsigned short BeBoB::CommandCodes::m_gCommandId = 0; Index: trunk/libffado/src/bebob/bebob_dl_codes.h =================================================================== --- trunk/libffado/src/bebob/bebob_dl_codes.h (revision 445) +++ trunk/libffado/src/bebob/bebob_dl_codes.h (revision 554) @@ -29,5 +29,5 @@ #include "fbtypes.h" -#include "libavc/avc_serialize.h" +#include "libavc/util/avc_serialize.h" namespace BeBoB { @@ -69,6 +69,6 @@ virtual ~CommandCodes(); - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); + virtual bool serialize( AVC::IOSSerialize& se ); + virtual bool deserialize( AVC::IISDeserialize& de ); virtual size_t getMaxSize(); @@ -127,6 +127,6 @@ virtual ~CommandCodesReset(); - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); + virtual bool serialize( AVC::IOSSerialize& se ); + virtual bool deserialize( AVC::IISDeserialize& de ); EStartMode getStartMode() const @@ -147,6 +147,6 @@ virtual ~CommandCodesProgramGUID(); - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); + virtual bool serialize( AVC::IOSSerialize& se ); + virtual bool deserialize( AVC::IISDeserialize& de ); fb_octlet_t getGUID() const @@ -177,6 +177,6 @@ virtual ~CommandCodesDownloadStart(); - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); + virtual bool serialize( AVC::IOSSerialize& se ); + virtual bool deserialize( AVC::IISDeserialize& de ); bool setDate( fb_octlet_t date ) @@ -218,6 +218,6 @@ virtual ~CommandCodesDownloadBlock(); - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); + virtual bool serialize( AVC::IOSSerialize& se ); + virtual bool deserialize( AVC::IISDeserialize& de ); bool setSeqNumber( fb_quadlet_t seqNumber ) @@ -247,6 +247,6 @@ virtual ~CommandCodesDownloadEnd(); - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); + virtual bool serialize( AVC::IOSSerialize& se ); + virtual bool deserialize( AVC::IISDeserialize& de ); fb_quadlet_t getRespCrc32() const @@ -268,6 +268,6 @@ virtual ~CommandCodesInitializePersParam(); - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); + virtual bool serialize( AVC::IOSSerialize& se ); + virtual bool deserialize( AVC::IISDeserialize& de ); }; @@ -280,6 +280,6 @@ virtual ~CommandCodesInitializeConfigToFactorySetting(); - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); + virtual bool serialize( AVC::IOSSerialize& se ); + virtual bool deserialize( AVC::IISDeserialize& de ); }; @@ -296,6 +296,6 @@ virtual ~CommandCodesGo(); - virtual bool serialize( IOSSerialize& se ); - virtual bool deserialize( IISDeserialize& de ); + virtual bool serialize( AVC::IOSSerialize& se ); + virtual bool deserialize( AVC::IISDeserialize& de ); EStartMode getStartMode() const Index: trunk/libffado/src/bebob/bebob_avdevice.cpp =================================================================== --- trunk/libffado/src/bebob/bebob_avdevice.cpp (revision 537) +++ trunk/libffado/src/bebob/bebob_avdevice.cpp (revision 554) @@ -29,9 +29,9 @@ #include "libieee1394/ieee1394service.h" -#include "libavc/avc_plug_info.h" -#include "libavc/avc_extended_plug_info.h" -#include "libavc/avc_subunit_info.h" -#include "libavc/avc_extended_stream_format.h" -#include "libavc/avc_serialize.h" +#include "libavc/general/avc_plug_info.h" +#include "libavc/general/avc_extended_plug_info.h" +#include "libavc/general/avc_subunit_info.h" +#include "libavc/streamformat/avc_extended_stream_format.h" +#include "libavc/util/avc_serialize.h" #include "libavc/avc_definitions.h" @@ -43,7 +43,9 @@ #include +using namespace AVC; + namespace BeBoB { -static VendorModelEntry supportedDeviceList[] = +static GenericAVC::VendorModelEntry supportedDeviceList[] = { {0x00000f, 0x00010065, "Mackie", "Onyx Firewire"}, @@ -71,5 +73,4 @@ {0x000d6c, 0x00010062, "M-Audio", "FW Solo"}, {0x000d6c, 0x00010081, "M-Audio", "NRV10"}, - }; @@ -77,13 +78,9 @@ Ieee1394Service& ieee1394service, int nodeId ) - : IAvDevice( configRom, ieee1394service, nodeId ) - , m_pPlugManager( new AvPlugManager( DEBUG_LEVEL_NORMAL ) ) - , m_activeSyncInfo( 0 ) - , m_model ( NULL ) + : GenericAVC::AvDevice( configRom, ieee1394service, nodeId ) , m_Mixer ( NULL ) { debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::AvDevice (NodeID %d)\n", nodeId ); - addOption(Util::OptionContainer::Option("snoopMode",false)); } @@ -96,37 +93,38 @@ delete m_Mixer; } - - for ( AvDeviceSubunitVector::iterator it = m_subunits.begin(); - it != m_subunits.end(); - ++it ) - { - delete *it; - } - for ( AvPlugConnectionVector::iterator it = m_plugConnections.begin(); - it != m_plugConnections.end(); - ++it ) - { - delete *it; - } - for ( AvPlugVector::iterator it = m_pcrPlugs.begin(); - it != m_pcrPlugs.end(); - ++it ) - { - delete *it; - } - for ( AvPlugVector::iterator it = m_externalPlugs.begin(); - it != m_externalPlugs.end(); - ++it ) - { - delete *it; - } -} - -void -AvDevice::setVerboseLevel(int l) -{ -// m_pPlugManager->setVerboseLevel(l); - - IAvDevice::setVerboseLevel(l); +} + +AVC::Subunit* +AvDevice::createSubunit(AVC::Unit& unit, + AVC::ESubunitType type, + AVC::subunit_t id ) +{ + switch (type) { + case AVC::eST_Audio: + return new BeBoB::SubunitAudio(unit, id ); + case AVC::eST_Music: + return new BeBoB::SubunitMusic(unit, id ); + default: + return NULL; + } +} + +AVC::Plug * +AvDevice::createPlug( AVC::Unit* unit, + AVC::Subunit* subunit, + AVC::function_block_type_t functionBlockType, + AVC::function_block_type_t functionBlockId, + AVC::Plug::EPlugAddressType plugAddressType, + AVC::Plug::EPlugDirection plugDirection, + AVC::plug_id_t plugId ) +{ + + return new BeBoB::Plug( unit, + subunit, + functionBlockType, + functionBlockId, + plugAddressType, + plugDirection, + plugId ); } @@ -140,5 +138,5 @@ for ( unsigned int i = 0; - i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) ); + i < ( sizeof( supportedDeviceList )/sizeof( GenericAVC::VendorModelEntry ) ); ++i ) { @@ -149,5 +147,4 @@ } } - return false; } @@ -160,5 +157,5 @@ for ( unsigned int i = 0; - i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) ); + i < ( sizeof( supportedDeviceList )/sizeof( GenericAVC::VendorModelEntry ) ); ++i ) { @@ -177,28 +174,23 @@ } else return false; - if ( !enumerateSubUnits() ) { - debugError( "Could not enumarate sub units\n" ); - return false; - } - - if ( !discoverPlugs() ) { - debugError( "Detecting plugs failed\n" ); - return false; - } - - if ( !discoverPlugConnections() ) { - debugError( "Detecting plug connections failed\n" ); - return false; - } - - if ( !discoverSubUnitsPlugConnections() ) { - debugError( "Detecting plug connnection failed\n" ); - return false; - } - - if ( !discoverSyncModes() ) { - debugError( "Detecting sync modes failed\n" ); - return false; - } + if ( !Unit::discover() ) { + debugError( "Could not discover unit\n" ); + return false; + } + + if((getAudioSubunit( 0 ) == NULL)) { + debugError( "Unit doesn't have an Audio subunit.\n"); + return false; + } + if((getMusicSubunit( 0 ) == NULL)) { + debugError( "Unit doesn't have a Music subunit.\n"); + return false; + } + +// replaced by the previous Unit discovery +// if ( !enumerateSubUnits() ) { +// debugError( "Could not enumarate sub units\n" ); +// return false; +// } // create a GenericMixer and add it as an OSC child node @@ -210,5 +202,5 @@ delete m_Mixer; } - + // create the mixer & register it if(getAudioSubunit(0) == NULL) { @@ -225,617 +217,11 @@ bool -AvDevice::discoverPlugs() -{ - ////////////////////////////////////////////// - // Get number of available isochronous input - // and output plugs of unit - - PlugInfoCmd plugInfoCmd( *m_p1394Service ); - plugInfoCmd.setNodeId( m_pConfigRom->getNodeId() ); - plugInfoCmd.setCommandType( AVCCommand::eCT_Status ); - plugInfoCmd.setVerbose( m_verboseLevel ); - - if ( !plugInfoCmd.fire() ) { - debugError( "plug info command failed\n" ); - return false; - } - - debugOutput( DEBUG_LEVEL_NORMAL, "number of iso input plugs = %d\n", - plugInfoCmd.m_serialBusIsochronousInputPlugs ); - debugOutput( DEBUG_LEVEL_NORMAL, "number of iso output plugs = %d\n", - plugInfoCmd.m_serialBusIsochronousOutputPlugs ); - debugOutput( DEBUG_LEVEL_NORMAL, "number of external input plugs = %d\n", - plugInfoCmd.m_externalInputPlugs ); - debugOutput( DEBUG_LEVEL_NORMAL, "number of external output plugs = %d\n", - plugInfoCmd.m_externalOutputPlugs ); - - if ( !discoverPlugsPCR( AvPlug::eAPD_Input, - plugInfoCmd.m_serialBusIsochronousInputPlugs ) ) - { - debugError( "pcr input plug discovering failed\n" ); - return false; - } - - if ( !discoverPlugsPCR( AvPlug::eAPD_Output, - plugInfoCmd.m_serialBusIsochronousOutputPlugs ) ) - { - debugError( "pcr output plug discovering failed\n" ); - return false; - } - - if ( !discoverPlugsExternal( AvPlug::eAPD_Input, - plugInfoCmd.m_externalInputPlugs ) ) - { - debugError( "external input plug discovering failed\n" ); - return false; - } - - if ( !discoverPlugsExternal( AvPlug::eAPD_Output, - plugInfoCmd.m_externalOutputPlugs ) ) - { - debugError( "external output plug discovering failed\n" ); - return false; - } - +AvDevice::propagatePlugInfo() { + // we don't have to propagate since we discover things + // another way + debugOutput(DEBUG_LEVEL_VERBOSE, "Skip plug info propagation\n"); return true; } -bool -AvDevice::discoverPlugsPCR( AvPlug::EAvPlugDirection plugDirection, - plug_id_t plugMaxId ) -{ - for ( int plugId = 0; - plugId < plugMaxId; - ++plugId ) - { - AvPlug* plug = new AvPlug( *m_p1394Service, - *m_pConfigRom, - *m_pPlugManager, - AVCCommand::eST_Unit, - 0xff, - 0xff, - 0xff, - AvPlug::eAPA_PCR, - plugDirection, - plugId, - m_verboseLevel ); - if ( !plug || !plug->discover() ) { - debugError( "plug discovering failed\n" ); - delete plug; - return false; - } - - debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n", - plug->getName() ); - m_pcrPlugs.push_back( plug ); - } - - return true; -} - -bool -AvDevice::discoverPlugsExternal( AvPlug::EAvPlugDirection plugDirection, - plug_id_t plugMaxId ) -{ - for ( int plugId = 0; - plugId < plugMaxId; - ++plugId ) - { - AvPlug* plug = new AvPlug( *m_p1394Service, - *m_pConfigRom, - *m_pPlugManager, - AVCCommand::eST_Unit, - 0xff, - 0xff, - 0xff, - AvPlug::eAPA_ExternalPlug, - plugDirection, - plugId, - m_verboseLevel ); - if ( !plug || !plug->discover() ) { - debugError( "plug discovering failed\n" ); - return false; - } - - debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n", - plug->getName() ); - m_externalPlugs.push_back( plug ); - } - - return true; -} - -bool -AvDevice::discoverPlugConnections() -{ - for ( AvPlugVector::iterator it = m_pcrPlugs.begin(); - it != m_pcrPlugs.end(); - ++it ) - { - AvPlug* plug = *it; - if ( !plug->discoverConnections() ) { - debugError( "Could not discover plug connections\n" ); - return false; - } - } - for ( AvPlugVector::iterator it = m_externalPlugs.begin(); - it != m_externalPlugs.end(); - ++it ) - { - AvPlug* plug = *it; - if ( !plug->discoverConnections() ) { - debugError( "Could not discover plug connections\n" ); - return false; - } - } - - return true; -} - -bool -AvDevice::discoverSubUnitsPlugConnections() -{ - for ( AvDeviceSubunitVector::iterator it = m_subunits.begin(); - it != m_subunits.end(); - ++it ) - { - AvDeviceSubunit* subunit = *it; - if ( !subunit->discoverConnections() ) { - debugError( "Subunit '%s' plug connections failed\n", - subunit->getName() ); - return false; - } - } - return true; -} - -bool -AvDevice::discoverSyncModes() -{ - // Following possible sync plugs exists: - // - Music subunit sync output plug = internal sync (CSP) - // - Unit input plug 0 = SYT match - // - Unit input plut 1 = Sync stream - // - // If last sync mode is reported it is mostelikely not - // implemented *sic* - // - // Following sync sources are device specific: - // - All unit external input plugs which have a - // sync information (WS, SPDIF, ...) - - // First we have to find the sync input and output plug - // in the music subunit. - - // Note PCR input means 1394bus-to-device where as - // MSU input means subunit-to-device - - AvPlugVector syncPCRInputPlugs = getPlugsByType( m_pcrPlugs, - AvPlug::eAPD_Input, - AvPlug::eAPT_Sync ); - if ( !syncPCRInputPlugs.size() ) { - debugWarning( "No PCR sync input plug found\n" ); - } - - AvPlugVector syncPCROutputPlugs = getPlugsByType( m_pcrPlugs, - AvPlug::eAPD_Output, - AvPlug::eAPT_Sync ); - if ( !syncPCROutputPlugs.size() ) { - debugWarning( "No PCR sync output plug found\n" ); - } - - AvPlugVector isoPCRInputPlugs = getPlugsByType( m_pcrPlugs, - AvPlug::eAPD_Input, - AvPlug::eAPT_IsoStream ); - if ( !isoPCRInputPlugs.size() ) { - debugWarning( "No PCR iso input plug found\n" ); - - } - - AvPlugVector isoPCROutputPlugs = getPlugsByType( m_pcrPlugs, - AvPlug::eAPD_Output, - AvPlug::eAPT_IsoStream ); - if ( !isoPCROutputPlugs.size() ) { - debugWarning( "No PCR iso output plug found\n" ); - - } - - AvPlugVector digitalExternalInputPlugs = getPlugsByType( m_externalPlugs, - AvPlug::eAPD_Input, - AvPlug::eAPT_Digital ); - if ( !digitalExternalInputPlugs.size() ) { - debugOutput( DEBUG_LEVEL_VERBOSE, "No external digital input plugs found\n" ); - - } - - AvPlugVector syncExternalInputPlugs = getPlugsByType( m_externalPlugs, - AvPlug::eAPD_Input, - AvPlug::eAPT_Sync ); - if ( !syncExternalInputPlugs.size() ) { - debugOutput( DEBUG_LEVEL_VERBOSE, "No external sync input plugs found\n" ); - - } - - AvPlugVector syncMSUInputPlugs = m_pPlugManager->getPlugsByType( - AVCCommand::eST_Music, - 0, - 0xff, - 0xff, - AvPlug::eAPA_SubunitPlug, - AvPlug::eAPD_Input, - AvPlug::eAPT_Sync ); - if ( !syncMSUInputPlugs.size() ) { - debugWarning( "No sync input plug for MSU subunit found\n" ); - } - - AvPlugVector syncMSUOutputPlugs = m_pPlugManager->getPlugsByType( - AVCCommand::eST_Music, - 0, - 0xff, - 0xff, - AvPlug::eAPA_SubunitPlug, - AvPlug::eAPD_Output, - AvPlug::eAPT_Sync ); - if ( !syncMSUOutputPlugs.size() ) { - debugWarning( "No sync output plug for MSU subunit found\n" ); - } - - debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Sync Input Plugs:\n" ); - showAvPlugs( syncPCRInputPlugs ); - debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Sync Output Plugs:\n" ); - showAvPlugs( syncPCROutputPlugs ); - debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Iso Input Plugs:\n" ); - showAvPlugs( isoPCRInputPlugs ); - debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Iso Output Plugs:\n" ); - showAvPlugs( isoPCROutputPlugs ); - debugOutput( DEBUG_LEVEL_VERBOSE, "External digital Input Plugs:\n" ); - showAvPlugs( digitalExternalInputPlugs ); - debugOutput( DEBUG_LEVEL_VERBOSE, "External sync Input Plugs:\n" ); - showAvPlugs( syncExternalInputPlugs ); - debugOutput( DEBUG_LEVEL_VERBOSE, "MSU Sync Input Plugs:\n" ); - showAvPlugs( syncMSUInputPlugs ); - debugOutput( DEBUG_LEVEL_VERBOSE, "MSU Sync Output Plugs:\n" ); - showAvPlugs( syncMSUOutputPlugs ); - - // Check all possible PCR input to MSU input connections - // -> sync stream input - checkSyncConnectionsAndAddToList( syncPCRInputPlugs, - syncMSUInputPlugs, - "Sync Stream Input" ); - - // Check all possible MSU output to PCR output connections - // -> sync stream output - checkSyncConnectionsAndAddToList( syncMSUOutputPlugs, - syncPCROutputPlugs, - "Sync Stream Output" ); - - // Check all PCR iso input to MSU input connections - // -> SYT match - checkSyncConnectionsAndAddToList( isoPCRInputPlugs, - syncMSUInputPlugs, - "Syt Match" ); - - // Check all MSU sync output to MSU input connections - // -> CSP - checkSyncConnectionsAndAddToList( syncMSUOutputPlugs, - syncMSUInputPlugs, - "Internal (CSP)" ); - - // Check all external digital input to MSU input connections - // -> SPDIF/ADAT sync - checkSyncConnectionsAndAddToList( digitalExternalInputPlugs, - syncMSUInputPlugs, - "Digital Input Sync" ); - - // Check all external sync input to MSU input connections - // -> SPDIF/ADAT sync - checkSyncConnectionsAndAddToList( syncExternalInputPlugs, - syncMSUInputPlugs, - "Digital Input Sync" ); - - // Currently active connection signal source cmd, command type - // status, source unknown, destination MSU sync input plug - - for ( AvPlugVector::const_iterator it = syncMSUInputPlugs.begin(); - it != syncMSUInputPlugs.end(); - ++it ) - { - AvPlug* msuPlug = *it; - for ( AvPlugVector::const_iterator jt = - msuPlug->getInputConnections().begin(); - jt != msuPlug->getInputConnections().end(); - ++jt ) - { - AvPlug* plug = *jt; - - for ( SyncInfoVector::iterator it = m_syncInfos.begin(); - it != m_syncInfos.end(); - ++it ) - { - SyncInfo* pSyncInfo = &*it; - if ( ( pSyncInfo->m_source == plug ) - && ( pSyncInfo->m_destination == msuPlug ) ) - { - m_activeSyncInfo = pSyncInfo; - break; - } - } - debugOutput( DEBUG_LEVEL_NORMAL, - "Active Sync Connection: '%s' -> '%s'\n", - plug->getName(), - msuPlug->getName() ); - } - } - - return true; -} - -bool -AvDevice::enumerateSubUnits() -{ - bool musicSubunitFound=false; - bool audioSubunitFound=false; - - SubUnitInfoCmd subUnitInfoCmd( *m_p1394Service ); - //subUnitInfoCmd.setVerbose( 1 ); - subUnitInfoCmd.setCommandType( AVCCommand::eCT_Status ); - - // BeBoB has always exactly one audio and one music subunit. This - // means is fits into the first page of the SubUnitInfo command. - // So there is no need to do more than needed - - subUnitInfoCmd.m_page = 0; - subUnitInfoCmd.setNodeId( m_pConfigRom->getNodeId() ); - subUnitInfoCmd.setVerbose( m_verboseLevel ); - if ( !subUnitInfoCmd.fire() ) { - debugError( "Subunit info command failed\n" ); - // shouldn't this be an error situation? - return false; - } - - for ( int i = 0; i < subUnitInfoCmd.getNrOfValidEntries(); ++i ) { - subunit_type_t subunit_type - = subUnitInfoCmd.m_table[i].m_subunit_type; - - unsigned int subunitId = getNrOfSubunits( subunit_type ); - - debugOutput( DEBUG_LEVEL_VERBOSE, - "subunit_id = %2d, subunit_type = %2d (%s)\n", - subunitId, - subunit_type, - subunitTypeToString( subunit_type ) ); - - AvDeviceSubunit* subunit = 0; - switch( subunit_type ) { - case AVCCommand::eST_Audio: - subunit = new AvDeviceSubunitAudio( *this, - subunitId, - m_verboseLevel ); - if ( !subunit ) { - debugFatal( "Could not allocate AvDeviceSubunitAudio\n" ); - return false; - } - - m_subunits.push_back( subunit ); - audioSubunitFound=true; - - break; - case AVCCommand::eST_Music: - subunit = new AvDeviceSubunitMusic( *this, - subunitId, - m_verboseLevel ); - if ( !subunit ) { - debugFatal( "Could not allocate AvDeviceSubunitMusic\n" ); - return false; - } - - m_subunits.push_back( subunit ); - musicSubunitFound=true; - - break; - default: - debugOutput( DEBUG_LEVEL_NORMAL, - "Unsupported subunit found, subunit_type = %d (%s)\n", - subunit_type, - subunitTypeToString( subunit_type ) ); - continue; - - } - - if ( !subunit->discover() ) { - debugError( "enumerateSubUnits: Could not discover " - "subunit_id = %2d, subunit_type = %2d (%s)\n", - subunitId, - subunit_type, - subunitTypeToString( subunit_type ) ); - delete subunit; - return false; - } - - } - - // a BeBoB always has an audio and a music subunit - return (musicSubunitFound && audioSubunitFound); -} - - -AvDeviceSubunit* -AvDevice::getSubunit( subunit_type_t subunitType, - subunit_id_t subunitId ) const -{ - for ( AvDeviceSubunitVector::const_iterator it = m_subunits.begin(); - it != m_subunits.end(); - ++it ) - { - AvDeviceSubunit* subunit = *it; - if ( ( subunitType == subunit->getSubunitType() ) - && ( subunitId == subunit->getSubunitId() ) ) - { - return subunit; - } - } - - return 0; -} - - -unsigned int -AvDevice::getNrOfSubunits( subunit_type_t subunitType ) const -{ - unsigned int nrOfSubunits = 0; - - for ( AvDeviceSubunitVector::const_iterator it = m_subunits.begin(); - it != m_subunits.end(); - ++it ) - { - AvDeviceSubunit* subunit = *it; - if ( subunitType == subunit->getSubunitType() ) { - nrOfSubunits++; - } - } - - return nrOfSubunits; -} - -AvPlugConnection* -AvDevice::getPlugConnection( AvPlug& srcPlug ) const -{ - for ( AvPlugConnectionVector::const_iterator it - = m_plugConnections.begin(); - it != m_plugConnections.end(); - ++it ) - { - AvPlugConnection* plugConnection = *it; - if ( &( plugConnection->getSrcPlug() ) == &srcPlug ) { - return plugConnection; - } - } - - return 0; -} - -AvPlug* -AvDevice::getPlugById( AvPlugVector& plugs, - AvPlug::EAvPlugDirection plugDirection, - int id ) -{ - for ( AvPlugVector::iterator it = plugs.begin(); - it != plugs.end(); - ++it ) - { - AvPlug* plug = *it; - if ( ( id == plug->getPlugId() ) - && ( plugDirection == plug->getPlugDirection() ) ) - { - return plug; - } - } - - return 0; -} - -AvPlugVector -AvDevice::getPlugsByType( AvPlugVector& plugs, - AvPlug::EAvPlugDirection plugDirection, - AvPlug::EAvPlugType type) -{ - AvPlugVector plugVector; - for ( AvPlugVector::iterator it = plugs.begin(); - it != plugs.end(); - ++it ) - { - AvPlug* plug = *it; - if ( ( type == plug->getPlugType() ) - && ( plugDirection == plug->getPlugDirection() ) ) - { - plugVector.push_back( plug ); - } - } - - return plugVector; -} - -AvPlug* -AvDevice::getSyncPlug( int maxPlugId, AvPlug::EAvPlugDirection ) -{ - return 0; -} - -bool -AvDevice::setSamplingFrequency( ESamplingFrequency samplingFrequency ) -{ - bool snoopMode=false; - if(!getOption("snoopMode", snoopMode)) { - debugWarning("Could not retrieve snoopMode parameter, defauling to false\n"); - } - - if(snoopMode) { - int current_sr=getSamplingFrequency(); - if (current_sr != convertESamplingFrequency( samplingFrequency ) ) { - debugError("In snoop mode it is impossible to set the sample rate.\n"); - debugError("Please start the client with the correct setting.\n"); - return false; - } - return true; - } else { - AvPlug* plug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Input, 0 ); - if ( !plug ) { - debugError( "setSampleRate: Could not retrieve iso input plug 0\n" ); - return false; - } - - if ( !setSamplingFrequencyPlug( *plug, - AvPlug::eAPD_Input, - samplingFrequency ) ) - { - debugError( "setSampleRate: Setting sample rate failed\n" ); - return false; - } - - plug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Output, 0 ); - if ( !plug ) { - debugError( "setSampleRate: Could not retrieve iso output plug 0\n" ); - return false; - } - - if ( !setSamplingFrequencyPlug( *plug, - AvPlug::eAPD_Output, - samplingFrequency ) ) - { - debugError( "setSampleRate: Setting sample rate failed\n" ); - return false; - } - - debugOutput( DEBUG_LEVEL_VERBOSE, - "setSampleRate: Set sample rate to %d\n", - convertESamplingFrequency( samplingFrequency ) ); - return true; - } - // not executable - return false; -} - -int -AvDevice::getSamplingFrequency( ) -{ - AvPlug* inputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Input, 0 ); - if ( !inputPlug ) { - debugError( "setSampleRate: Could not retrieve iso input plug 0\n" ); - return false; - } - AvPlug* outputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Output, 0 ); - if ( !outputPlug ) { - debugError( "setSampleRate: Could not retrieve iso output plug 0\n" ); - return false; - } - - int samplerate_playback=inputPlug->getSampleRate(); - int samplerate_capture=outputPlug->getSampleRate(); - - if (samplerate_playback != samplerate_capture) { - debugWarning("Samplerates for capture and playback differ!\n"); - } - return samplerate_capture; -} int @@ -916,5 +302,5 @@ signalSourceCmd.setSignalDestination( signalUnitAddr ); signalSourceCmd.setNodeId( m_nodeId ); - signalSourceCmd.setSubunitType( AVCCommand::eST_Unit ); + signalSourceCmd.setSubunitType( eST_Unit ); signalSourceCmd.setSubunitId( 0xff ); @@ -957,526 +343,4 @@ } -bool -AvDevice::setSamplingFrequencyPlug( AvPlug& plug, - AvPlug::EAvPlugDirection direction, - ESamplingFrequency samplingFrequency ) -{ - - ExtendedStreamFormatCmd extStreamFormatCmd( - *m_p1394Service, - ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommandList ); - UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, - plug.getPlugId() ); - - extStreamFormatCmd.setPlugAddress( - PlugAddress( - AvPlug::convertPlugDirection(direction ), - PlugAddress::ePAM_Unit, - unitPlugAddress ) ); - - extStreamFormatCmd.setNodeId( m_pConfigRom->getNodeId() ); - extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status ); - - int i = 0; - bool cmdSuccess = false; - bool correctFormatFound = false; - - do { - extStreamFormatCmd.setIndexInStreamFormat( i ); - extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status ); - extStreamFormatCmd.setVerbose( m_verboseLevel ); - - cmdSuccess = extStreamFormatCmd.fire(); - - if ( cmdSuccess - && ( extStreamFormatCmd.getResponse() == - AVCCommand::eR_Implemented ) ) - { - ESamplingFrequency foundFreq = eSF_DontCare; - - FormatInformation* formatInfo = - extStreamFormatCmd.getFormatInformation(); - FormatInformationStreamsCompound* compoundStream - = dynamic_cast< FormatInformationStreamsCompound* > ( - formatInfo->m_streams ); - if ( compoundStream ) { - foundFreq = - static_cast< ESamplingFrequency >( - compoundStream->m_samplingFrequency ); - } - - FormatInformationStreamsSync* syncStream - = dynamic_cast< FormatInformationStreamsSync* > ( - formatInfo->m_streams ); - if ( syncStream ) { - foundFreq = - static_cast< ESamplingFrequency >( - syncStream->m_samplingFrequency ); - } - - if ( foundFreq == samplingFrequency ) - { - correctFormatFound = true; - break; - } - } - - ++i; - } while ( cmdSuccess - && ( extStreamFormatCmd.getResponse() == - ExtendedStreamFormatCmd::eR_Implemented ) ); - - if ( !cmdSuccess ) { - debugError( "setSampleRatePlug: Failed to retrieve format info\n" ); - return false; - } - - if ( !correctFormatFound ) { - debugError( "setSampleRatePlug: %s plug %d does not support " - "sample rate %d\n", - plug.getName(), - plug.getPlugId(), - convertESamplingFrequency( samplingFrequency ) ); - return false; - } - - extStreamFormatCmd.setSubFunction( - ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommand ); - extStreamFormatCmd.setCommandType( AVCCommand::eCT_Control ); - extStreamFormatCmd.setVerbose( m_verboseLevel ); - - if ( !extStreamFormatCmd.fire() ) { - debugError( "setSampleRate: Could not set sample rate %d " - "to %s plug %d\n", - convertESamplingFrequency( samplingFrequency ), - plug.getName(), - plug.getPlugId() ); - return false; - } - - return true; -} - -void -AvDevice::showDevice() -{ - debugOutput(DEBUG_LEVEL_VERBOSE, - "%s %s at node %d\n", m_model->vendor_name, m_model->model_name, - m_nodeId); - - m_pPlugManager->showPlugs(); -} - -void -AvDevice::showAvPlugs( AvPlugVector& plugs ) const -{ - int i = 0; - for ( AvPlugVector::const_iterator it = plugs.begin(); - it != plugs.end(); - ++it, ++i ) - { - AvPlug* plug = *it; - debugOutput( DEBUG_LEVEL_VERBOSE, "Plug %d\n", i ); - plug->showPlug(); - } -} - -bool -AvDevice::checkSyncConnectionsAndAddToList( AvPlugVector& plhs, - AvPlugVector& prhs, - std::string syncDescription ) -{ - for ( AvPlugVector::iterator plIt = plhs.begin(); - plIt != plhs.end(); - ++plIt ) - { - AvPlug* pl = *plIt; - for ( AvPlugVector::iterator prIt = prhs.begin(); - prIt != prhs.end(); - ++prIt ) - { - AvPlug* pr = *prIt; - if ( pl->inquireConnnection( *pr ) ) { - m_syncInfos.push_back( SyncInfo( *pl, *pr, syncDescription ) ); - debugOutput( DEBUG_LEVEL_NORMAL, - "Sync connection '%s' -> '%s'\n", - pl->getName(), - pr->getName() ); - } - } - } - return true; -} - -bool AvDevice::setActiveSync(const SyncInfo& syncInfo) -{ - return syncInfo.m_source->setConnection( *syncInfo.m_destination ); -} - -bool -AvDevice::lock() { - bool snoopMode=false; - if(!getOption("snoopMode", snoopMode)) { - debugWarning("Could not retrieve snoopMode parameter, defauling to false\n"); - } - - if (snoopMode) { - // don't lock - } else { - - } - - return true; -} - -bool -AvDevice::unlock() { - bool snoopMode=false; - if(!getOption("snoopMode", snoopMode)) { - debugWarning("Could not retrieve snoopMode parameter, defauling to false\n"); - } - - if (snoopMode) { - // don't unlock - } else { - - } - return true; -} - -bool -AvDevice::prepare() { - bool snoopMode=false; - if(!getOption("snoopMode", snoopMode)) { - debugWarning("Could not retrieve snoopMode parameter, defauling to false\n"); - } - - /////////// - // get plugs - - AvPlug* inputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Input, 0 ); - if ( !inputPlug ) { - debugError( "setSampleRate: Could not retrieve iso input plug 0\n" ); - return false; - } - AvPlug* outputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Output, 0 ); - if ( !outputPlug ) { - debugError( "setSampleRate: Could not retrieve iso output plug 0\n" ); - return false; - } - - int samplerate=outputPlug->getSampleRate(); - - debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing receive processor...\n"); - // create & add streamprocessors - Streaming::StreamProcessor *p; - - p=new Streaming::AmdtpReceiveStreamProcessor( - m_p1394Service->getPort(), - samplerate, - outputPlug->getNrOfChannels()); - - if(!p->init()) { - debugFatal("Could not initialize receive processor!\n"); - delete p; - return false; - } - - if (!addPlugToProcessor(*outputPlug,p, - Streaming::Port::E_Capture)) { - debugFatal("Could not add plug to processor!\n"); - delete p; - return false; - } - - m_receiveProcessors.push_back(p); - - // do the transmit processor - debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing transmit processor%s...\n", - (snoopMode?" in snoop mode":"")); - if (snoopMode) { - // we are snooping, so this is receive too. - p=new Streaming::AmdtpReceiveStreamProcessor( - m_p1394Service->getPort(), - samplerate, - inputPlug->getNrOfChannels()); - } else { - p=new Streaming::AmdtpTransmitStreamProcessor( - m_p1394Service->getPort(), - samplerate, - inputPlug->getNrOfChannels()); - } - - if(!p->init()) { - debugFatal("Could not initialize transmit processor %s!\n", - (snoopMode?" in snoop mode":"")); - delete p; - return false; - } - - if (snoopMode) { - if (!addPlugToProcessor(*inputPlug,p, - Streaming::Port::E_Capture)) { - debugFatal("Could not add plug to processor!\n"); - return false; - } - } else { - if (!addPlugToProcessor(*inputPlug,p, - Streaming::Port::E_Playback)) { - debugFatal("Could not add plug to processor!\n"); - return false; - } - } - - // we put this SP into the transmit SP vector, - // no matter if we are in snoop mode or not - // this allows us to find out what direction - // a certain stream should have. - m_transmitProcessors.push_back(p); - - return true; -} - -bool -AvDevice::addPlugToProcessor( - AvPlug& plug, - Streaming::StreamProcessor *processor, - Streaming::AmdtpAudioPort::E_Direction direction) { - - std::string id=std::string("dev?"); - if(!getOption("id", id)) { - debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n"); - } - - AvPlug::ClusterInfoVector& clusterInfos = plug.getClusterInfos(); - for ( AvPlug::ClusterInfoVector::const_iterator it = clusterInfos.begin(); - it != clusterInfos.end(); - ++it ) - { - const AvPlug::ClusterInfo* clusterInfo = &( *it ); - - AvPlug::ChannelInfoVector channelInfos = clusterInfo->m_channelInfos; - for ( AvPlug::ChannelInfoVector::const_iterator it = channelInfos.begin(); - it != channelInfos.end(); - ++it ) - { - const AvPlug::ChannelInfo* channelInfo = &( *it ); - std::ostringstream portname; - - portname << id << "_" << channelInfo->m_name; - - Streaming::Port *p=NULL; - switch(clusterInfo->m_portType) { - case ExtendedPlugInfoClusterInfoSpecificData::ePT_Speaker: - case ExtendedPlugInfoClusterInfoSpecificData::ePT_Headphone: - case ExtendedPlugInfoClusterInfoSpecificData::ePT_Microphone: - case ExtendedPlugInfoClusterInfoSpecificData::ePT_Line: - case ExtendedPlugInfoClusterInfoSpecificData::ePT_Analog: - p=new Streaming::AmdtpAudioPort( - portname.str(), - direction, - // \todo: streaming backend expects indexing starting from 0 - // but bebob reports it starting from 1. Decide where - // and how to handle this (pp: here) - channelInfo->m_streamPosition - 1, - channelInfo->m_location - 1, - Streaming::AmdtpPortInfo::E_MBLA - ); - break; - - case ExtendedPlugInfoClusterInfoSpecificData::ePT_MIDI: - p=new Streaming::AmdtpMidiPort( - portname.str(), - direction, - // \todo: streaming backend expects indexing starting from 0 - // but bebob reports it starting from 1. Decide where - // and how to handle this (pp: here) - channelInfo->m_streamPosition - 1, - channelInfo->m_location - 1, - Streaming::AmdtpPortInfo::E_Midi - ); - - break; - case ExtendedPlugInfoClusterInfoSpecificData::ePT_SPDIF: - case ExtendedPlugInfoClusterInfoSpecificData::ePT_ADAT: - case ExtendedPlugInfoClusterInfoSpecificData::ePT_TDIF: - case ExtendedPlugInfoClusterInfoSpecificData::ePT_MADI: - case ExtendedPlugInfoClusterInfoSpecificData::ePT_Digital: - p=new Streaming::AmdtpAudioPort( - portname.str(), - direction, - // \todo: streaming backend expects indexing starting from 0 - // but bebob reports it starting from 1. Decide where - // and how to handle this (pp: here) - channelInfo->m_streamPosition - 1, - channelInfo->m_location - 1, - Streaming::AmdtpPortInfo::E_MBLA - ); - break; - case ExtendedPlugInfoClusterInfoSpecificData::ePT_NoType: - default: - // unsupported - break; - } - - if (!p) { - debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str()); - } else { - - if (!processor->addPort(p)) { - debugWarning("Could not register port with stream processor\n"); - return false; - } - } - } - } - return true; -} - -int -AvDevice::getStreamCount() { - return m_receiveProcessors.size() + m_transmitProcessors.size(); -} - -Streaming::StreamProcessor * -AvDevice::getStreamProcessorByIndex(int i) { - - if (i<(int)m_receiveProcessors.size()) { - return m_receiveProcessors.at(i); - } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) { - return m_transmitProcessors.at(i-m_receiveProcessors.size()); - } - - return NULL; -} - -bool -AvDevice::startStreamByIndex(int i) { - int iso_channel=-1; - bool snoopMode=false; - if(!getOption("snoopMode", snoopMode)) { - debugWarning("Could not retrieve snoopMode parameter, defauling to false\n"); - } - - if (i<(int)m_receiveProcessors.size()) { - int n=i; - Streaming::StreamProcessor *p=m_receiveProcessors.at(n); - - if(snoopMode) { // a stream from the device to another host - // FIXME: put this into a decent framework! - // we should check the oPCR[n] on the device - struct iec61883_oPCR opcr; - if (iec61883_get_oPCRX( - m_p1394Service->getHandle(), - m_pConfigRom->getNodeId() | 0xffc0, - (quadlet_t *)&opcr, - n)) { - - debugWarning("Error getting the channel for SP %d\n",i); - return false; - } - - iso_channel=opcr.channel; - } else { - iso_channel=m_p1394Service->allocateIsoChannelCMP( - m_pConfigRom->getNodeId() | 0xffc0, n, - m_p1394Service->getLocalNodeId()| 0xffc0, -1); - } - if (iso_channel<0) { - debugError("Could not allocate ISO channel for SP %d\n",i); - return false; - } - - debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel); - - p->setChannel(iso_channel); - return true; - - } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) { - int n=i-m_receiveProcessors.size(); - Streaming::StreamProcessor *p=m_transmitProcessors.at(n); - - if(snoopMode) { // a stream from another host to the device - // FIXME: put this into a decent framework! - // we should check the iPCR[n] on the device - struct iec61883_iPCR ipcr; - if (iec61883_get_iPCRX( - m_p1394Service->getHandle(), - m_pConfigRom->getNodeId() | 0xffc0, - (quadlet_t *)&ipcr, - n)) { - - debugWarning("Error getting the channel for SP %d\n",i); - return false; - } - - iso_channel=ipcr.channel; - - } else { - iso_channel=m_p1394Service->allocateIsoChannelCMP( - m_p1394Service->getLocalNodeId()| 0xffc0, -1, - m_pConfigRom->getNodeId() | 0xffc0, n); - } - - if (iso_channel<0) { - debugError("Could not allocate ISO channel for SP %d\n",i); - return false; - } - - debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel); - - p->setChannel(iso_channel); - return true; - } - - debugError("SP index %d out of range!\n",i); - return false; -} - -bool -AvDevice::stopStreamByIndex(int i) { - bool snoopMode=false; - if(!getOption("snoopMode", snoopMode)) { - debugWarning("Could not retrieve snoopMode parameter, defauling to false\n"); - } - - if (i<(int)m_receiveProcessors.size()) { - int n=i; - Streaming::StreamProcessor *p=m_receiveProcessors.at(n); - - if(snoopMode) { - - } else { - // deallocate ISO channel - if(!m_p1394Service->freeIsoChannel(p->getChannel())) { - debugError("Could not deallocate iso channel for SP %d\n",i); - return false; - } - } - p->setChannel(-1); - - return true; - - } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) { - int n=i-m_receiveProcessors.size(); - Streaming::StreamProcessor *p=m_transmitProcessors.at(n); - - if(snoopMode) { - - } else { - // deallocate ISO channel - if(!m_p1394Service->freeIsoChannel(p->getChannel())) { - debugError("Could not deallocate iso channel for SP %d\n",i); - return false; - } - } - p->setChannel(-1); - - return true; - } - - debugError("SP index %d out of range!\n",i); - return false; -} template bool serializeVector( Glib::ustring path, @@ -1497,5 +361,5 @@ template bool deserializeVector( Glib::ustring path, Util::IODeserialize& deser, - AvDevice& avDevice, + Unit& avDevice, VT& vec ) { @@ -1520,87 +384,4 @@ bool -AvDevice::serializeSyncInfoVector( Glib::ustring basePath, - Util::IOSerialize& ser, - const SyncInfoVector& vec ) const -{ - bool result = true; - int i = 0; - - for ( SyncInfoVector::const_iterator it = vec.begin(); - it != vec.end(); - ++it ) - { - const SyncInfo& info = *it; - - std::ostringstream strstrm; - strstrm << basePath << i << "/"; - - result &= ser.write( strstrm.str() + "m_source", info.m_source->getGlobalId() ); - result &= ser.write( strstrm.str() + "m_destination", info.m_destination->getGlobalId() ); - result &= ser.write( strstrm.str() + "m_description", Glib::ustring( info.m_description ) ); - - i++; - } - - return result; -} - -bool -AvDevice::deserializeSyncInfoVector( Glib::ustring basePath, - Util::IODeserialize& deser, - SyncInfoVector& vec ) -{ - int i = 0; - bool bFinished = false; - do { - bool result; - std::ostringstream strstrm; - strstrm << basePath << i << "/"; - - plug_id_t sourceId; - plug_id_t destinationId; - Glib::ustring description; - - if ( deser.isExisting( strstrm.str() + "m_source" ) ) { - result = deser.read( strstrm.str() + "m_source", sourceId ); - result &= deser.read( strstrm.str() + "m_destination", destinationId ); - result &= deser.read( strstrm.str() + "m_description", description ); - } else { - result = false; - } - - if ( result ) { - SyncInfo syncInfo; - syncInfo.m_source = m_pPlugManager->getPlug( sourceId ); - syncInfo.m_destination = m_pPlugManager->getPlug( destinationId ); - syncInfo.m_description = description; - - vec.push_back( syncInfo ); - i++; - } else { - bFinished = true; - } - } while ( !bFinished ); - - return true; -} - -static bool -deserializeAvPlugUpdateConnections( Glib::ustring path, - Util::IODeserialize& deser, - AvPlugVector& vec ) -{ - bool result = true; - for ( AvPlugVector::iterator it = vec.begin(); - it != vec.end(); - ++it ) - { - AvPlug* pPlug = *it; - result &= pPlug->deserializeUpdate( path, deser ); - } - return result; -} - -bool AvDevice::serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const @@ -1609,9 +390,10 @@ bool result; result = m_pConfigRom->serialize( basePath + "m_pConfigRom/", ser ); - result &= ser.write( basePath + "m_verboseLevel", m_verboseLevel ); - result &= m_pPlugManager->serialize( basePath + "AvPlug", ser ); // serialize all av plugs + result &= ser.write( basePath + "m_verboseLevel", getDebugLevel() ); + result &= m_pPlugManager->serialize( basePath + "Plug", ser ); // serialize all av plugs result &= serializeVector( basePath + "PlugConnection", ser, m_plugConnections ); result &= serializeVector( basePath + "Subunit", ser, m_subunits ); - result &= serializeSyncInfoVector( basePath + "SyncInfo", ser, m_syncInfos ); + #warning broken at echoaudio merge + //result &= serializeSyncInfoVector( basePath + "SyncInfo", ser, m_syncInfos ); int i = 0; @@ -1630,41 +412,40 @@ result &= serializeOptions( basePath + "Options", ser ); - // result &= ser.write( basePath + "m_id", id ); +// result &= ser.write( basePath + "m_id", id ); return result; } -bool +AvDevice* AvDevice::deserialize( Glib::ustring basePath, - Util::IODeserialize& deser ) -{ - bool result; - result = deser.read( basePath + "m_verboseLevel", m_verboseLevel ); - - delete m_pPlugManager; - m_pPlugManager = AvPlugManager::deserialize( basePath + "AvPlug", deser, *this ); - if ( !m_pPlugManager ) { - return false; - } - result &= deserializeAvPlugUpdateConnections( basePath + "AvPlug", deser, m_pcrPlugs ); - result &= deserializeAvPlugUpdateConnections( basePath + "AvPlug", deser, m_externalPlugs ); - result &= deserializeVector( basePath + "PlugConnnection", deser, *this, m_plugConnections ); - result &= deserializeVector( basePath + "Subunit", deser, *this, m_subunits ); - result &= deserializeSyncInfoVector( basePath + "SyncInfo", deser, m_syncInfos ); - - unsigned int i; - result &= deser.read( basePath + "m_activeSyncInfo", i ); - - if ( result ) { - if ( i < m_syncInfos.size() ) { - m_activeSyncInfo = &m_syncInfos[i]; - } - } - - result &= deserializeOptions( basePath + "Options", deser, *this ); - - return result; -} - + Util::IODeserialize& deser, + Ieee1394Service& ieee1394Service ) +{ + +// ConfigRom *configRom = +// ConfigRom::deserialize( basePath + "m_pConfigRom/", deser, ieee1394Service ); +// +// if ( !configRom ) { +// return NULL; +// } +// +// AvDevice* pDev = new AvDevice( +// std::auto_ptr(configRom), +// ieee1394Service, configRom->getNodeId()); +// +// if ( pDev ) { +// bool result; +// int verboseLevel; +// result = deser.read( basePath + "m_verboseLevel", verboseLevel ); +// setDebugLevel( verboseLevel ); +// +// result &= AVC::Unit::deserialize(basePath, pDev, deser, ieee1394Service); +// +// result &= deserializeOptions( basePath + "Options", deser, *pDev ); +// } +// +// return pDev; + return NULL; +} Glib::ustring @@ -1686,5 +467,5 @@ AvDevice::loadFromCache() { - Glib::ustring sDevicePath = getCachePath() + m_pConfigRom->getGuidString(); +/* Glib::ustring sDevicePath = getCachePath() + m_pConfigRom->getGuidString(); char* configId; @@ -1707,5 +488,6 @@ } - return result; + return result;*/ + return false; } @@ -1713,33 +495,34 @@ AvDevice::saveCache() { - // the path looks like this: - // PATH_TO_CACHE + GUID + CONFIGURATION_ID - - Glib::ustring sDevicePath = getCachePath() + m_pConfigRom->getGuidString(); - struct stat buf; - if ( stat( sDevicePath.c_str(), &buf ) == 0 ) { - if ( !S_ISDIR( buf.st_mode ) ) { - debugError( "\"%s\" is not a directory\n", sDevicePath.c_str() ); - return false; - } - } else { - if ( mkdir( sDevicePath.c_str(), S_IRWXU | S_IRWXG ) != 0 ) { - debugError( "Could not create \"%s\" directory\n", sDevicePath.c_str() ); - return false; - } - } - - char* configId; - asprintf(&configId, "%08x", BeBoB::AvDevice::getConfigurationId() ); - if ( !configId ) { - debugError( "Could not create id string\n" ); - return false; - } - Glib::ustring sFileName = sDevicePath + "/" + configId + ".xml"; - free( configId ); - debugOutput( DEBUG_LEVEL_NORMAL, "filename %s\n", sFileName.c_str() ); - - Util::XMLSerialize ser( sFileName ); - return serialize( "", ser ); +// // the path looks like this: +// // PATH_TO_CACHE + GUID + CONFIGURATION_ID +// +// Glib::ustring sDevicePath = getCachePath() + m_pConfigRom->getGuidString(); +// struct stat buf; +// if ( stat( sDevicePath.c_str(), &buf ) == 0 ) { +// if ( !S_ISDIR( buf.st_mode ) ) { +// debugError( "\"%s\" is not a directory\n", sDevicePath.c_str() ); +// return false; +// } +// } else { +// if ( mkdir( sDevicePath.c_str(), S_IRWXU | S_IRWXG ) != 0 ) { +// debugError( "Could not create \"%s\" directory\n", sDevicePath.c_str() ); +// return false; +// } +// } +// +// char* configId; +// asprintf(&configId, "%08x", BeBoB::AvDevice::getConfigurationId() ); +// if ( !configId ) { +// debugError( "Could not create id string\n" ); +// return false; +// } +// Glib::ustring sFileName = sDevicePath + "/" + configId + ".xml"; +// free( configId ); +// debugOutput( DEBUG_LEVEL_NORMAL, "filename %s\n", sFileName.c_str() ); +// +// Util::XMLSerialize ser( sFileName ); +// return serialize( "", ser ); + return false; } Index: trunk/libffado/src/bebob/GenericMixer.cpp =================================================================== --- trunk/libffado/src/bebob/GenericMixer.cpp (revision 462) +++ trunk/libffado/src/bebob/GenericMixer.cpp (revision 554) @@ -31,6 +31,6 @@ #include "libosc/OscResponse.h" -#include "libavc/avc_function_block.h" -#include "libavc/avc_serialize.h" +#include "libavc/audiosubunit/avc_function_block.h" +#include "libavc/util/avc_serialize.h" #include "libieee1394/ieee1394service.h" @@ -43,4 +43,5 @@ using namespace OSC; +using namespace AVC; namespace BeBoB { Index: trunk/libffado/src/bebob/bebob_avdevice.h =================================================================== --- trunk/libffado/src/bebob/bebob_avdevice.h (revision 529) +++ trunk/libffado/src/bebob/bebob_avdevice.h (revision 554) @@ -29,7 +29,9 @@ #include "debugmodule/debugmodule.h" #include "libavc/avc_definitions.h" -#include "libavc/avc_extended_cmd_generic.h" +#include "libavc/general/avc_extended_cmd_generic.h" +#include "libavc/general/avc_unit.h" +#include "libavc/general/avc_subunit.h" +#include "libavc/general/avc_plug.h" -#include "bebob/bebob_configparser.h" #include "bebob/bebob_avplug.h" #include "bebob/bebob_avdevice_subunit.h" @@ -42,5 +44,7 @@ #include "libutil/serialize.h" -#include "iavdevice.h" +#include "genericavc/avc_avdevice.h" + +#include "ffadodevice.h" #include @@ -49,9 +53,8 @@ class ConfigRom; class Ieee1394Service; -class SubunitPlugSpecificDataPlugAddress; namespace BeBoB { -class AvDevice : public IAvDevice { +class AvDevice : public GenericAVC::AvDevice { public: AvDevice( std::auto_ptr( configRom ), @@ -60,6 +63,4 @@ virtual ~AvDevice(); - void setVerboseLevel(int l); - static bool probe( ConfigRom& configRom ); virtual bool loadFromCache(); @@ -67,107 +68,25 @@ virtual bool discover(); - virtual bool setSamplingFrequency( ESamplingFrequency samplingFrequency ); - virtual int getSamplingFrequency( ); - - virtual int getStreamCount(); - virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i); - - virtual bool prepare(); - virtual bool lock(); - virtual bool unlock(); - - virtual bool startStreamByIndex(int i); - virtual bool stopStreamByIndex(int i); - - virtual void showDevice(); - - Ieee1394Service& get1394Service() - { return *m_p1394Service; } - - AvPlugManager& getPlugManager() - { return *m_pPlugManager; } - - struct SyncInfo { - SyncInfo( AvPlug& source, - AvPlug& destination, - std::string description ) - : m_source( &source ) - , m_destination( &destination ) - , m_description( description ) - {} - SyncInfo() - : m_source( 0 ) - , m_destination( 0 ) - , m_description( "" ) - {} - AvPlug* m_source; - AvPlug* m_destination; - std::string m_description; - }; - - typedef std::vector SyncInfoVector; - const SyncInfoVector& getSyncInfos() const - { return m_syncInfos; } - const SyncInfo* getActiveSyncInfo() const - { return m_activeSyncInfo; } - bool setActiveSync( const SyncInfo& syncInfo ); - - AvDeviceSubunitAudio* getAudioSubunit( subunit_id_t subunitId ) - { return dynamic_cast( - getSubunit( AVC1394_SUBUNIT_AUDIO , subunitId ));}; + virtual AVC::Subunit* createSubunit(AVC::Unit& unit, + AVC::ESubunitType type, + AVC::subunit_t id ); + virtual AVC::Plug *createPlug( AVC::Unit* unit, + AVC::Subunit* subunit, + AVC::function_block_type_t functionBlockType, + AVC::function_block_type_t functionBlockId, + AVC::Plug::EPlugAddressType plugAddressType, + AVC::Plug::EPlugDirection plugDirection, + AVC::plug_id_t plugId ); protected: + virtual bool propagatePlugInfo(); - bool enumerateSubUnits(); - - bool discoverPlugs(); - bool discoverPlugsPCR( AvPlug::EAvPlugDirection plugDirection, - plug_id_t plugMaxId ); - bool discoverPlugsExternal( AvPlug::EAvPlugDirection plugDirection, - plug_id_t plugMaxId ); - bool discoverPlugConnections(); - bool discoverSyncModes(); - bool discoverSubUnitsPlugConnections(); - - AvDeviceSubunit* getSubunit( subunit_type_t subunitType, - subunit_id_t subunitId ) const; - - unsigned int getNrOfSubunits( subunit_type_t subunitType ) const; - AvPlugConnection* getPlugConnection( AvPlug& srcPlug ) const; - - AvPlug* getSyncPlug( int maxPlugId, AvPlug::EAvPlugDirection ); - - AvPlug* getPlugById( AvPlugVector& plugs, - AvPlug::EAvPlugDirection plugDireciton, - int id ); - AvPlugVector getPlugsByType( AvPlugVector& plugs, - AvPlug::EAvPlugDirection plugDirection, - AvPlug::EAvPlugType type); - - bool addPlugToProcessor( AvPlug& plug, Streaming::StreamProcessor *processor, - Streaming::AmdtpAudioPort::E_Direction direction); - - bool setSamplingFrequencyPlug( AvPlug& plug, - AvPlug::EAvPlugDirection direction, - ESamplingFrequency samplingFrequency ); - - void showAvPlugs( AvPlugVector& plugs ) const; - - bool checkSyncConnectionsAndAddToList( AvPlugVector& plhs, - AvPlugVector& prhs, - std::string syncDescription ); - - +public: bool serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const; - bool deserialize( Glib::ustring basePath, - Util::IODeserialize& deser ); - bool serializeSyncInfoVector( Glib::ustring basePath, - Util::IOSerialize& ser, - const SyncInfoVector& vec ) const; - bool deserializeSyncInfoVector( Glib::ustring basePath, - Util::IODeserialize& deser, - SyncInfoVector& vec ); + static AvDevice* deserialize( Glib::ustring basePath, + Util::IODeserialize& deser, + Ieee1394Service& ieee1394Service ); int getConfigurationIdSampleRate(); - int getConfigurationIdNumberOfChannel( PlugAddress::EPlugDirection ePlugDirection ); + int getConfigurationIdNumberOfChannel( AVC::PlugAddress::EPlugDirection ePlugDirection ); int getConfigurationIdSyncMode(); int getConfigurationId(); @@ -176,18 +95,6 @@ protected: - AvPlugVector m_pcrPlugs; - AvPlugVector m_externalPlugs; - AvPlugConnectionVector m_plugConnections; - AvDeviceSubunitVector m_subunits; - AvPlugManager* m_pPlugManager; - SyncInfoVector m_syncInfos; - SyncInfo* m_activeSyncInfo; - VendorModelEntry* m_model; GenericMixer* m_Mixer; - // streaming stuff - typedef std::vector< Streaming::StreamProcessor * > StreamProcessorVector; - StreamProcessorVector m_receiveProcessors; - StreamProcessorVector m_transmitProcessors; }; Index: trunk/libffado/src/bebob/bebob_avplug.cpp =================================================================== --- trunk/libffado/src/bebob/bebob_avplug.cpp (revision 516) +++ trunk/libffado/src/bebob/bebob_avplug.cpp (revision 554) @@ -27,42 +27,27 @@ #include "libieee1394/ieee1394service.h" -#include "libavc/avc_serialize.h" +#include "libavc/util/avc_serialize.h" #include +using namespace AVC; + namespace BeBoB { -int AvPlug::m_globalIdCounter = 0; - -IMPL_DEBUG_MODULE( AvPlug, AvPlug, DEBUG_LEVEL_NORMAL ); -IMPL_DEBUG_MODULE( AvPlugManager, AvPlugManager, DEBUG_LEVEL_NORMAL ); - -AvPlug::AvPlug( Ieee1394Service& ieee1394Service, - ConfigRom& configRom, - AvPlugManager& plugManager, - AVCCommand::ESubunitType subunitType, - subunit_id_t subunitId, - function_block_type_t functionBlockType, - function_block_id_t functionBlockId, - EAvPlugAddressType plugAddressType, - EAvPlugDirection plugDirection, - plug_id_t plugId, - int verboseLevel ) - : m_p1394Service( &ieee1394Service ) - , m_pConfigRom( &configRom ) - , m_subunitType( subunitType ) - , m_subunitId( subunitId ) - , m_functionBlockType( functionBlockType ) - , m_functionBlockId( functionBlockId ) - , m_addressType( plugAddressType ) - , m_direction( plugDirection ) - , m_id( plugId ) - , m_infoPlugType( eAPT_Unknown ) - , m_nrOfChannels( 0 ) - , m_plugManager( &plugManager ) - , m_verboseLevel( verboseLevel ) - , m_globalId( m_globalIdCounter++ ) -{ - setDebugLevel( m_verboseLevel ); +Plug::Plug( AVC::Unit* unit, + AVC::Subunit* subunit, + AVC::function_block_type_t functionBlockType, + AVC::function_block_type_t functionBlockId, + AVC::Plug::EPlugAddressType plugAddressType, + AVC::Plug::EPlugDirection plugDirection, + AVC::plug_id_t plugId ) + : AVC::Plug( unit, + subunit, + functionBlockType, + functionBlockId, + plugAddressType, + plugDirection, + plugId ) +{ debugOutput( DEBUG_LEVEL_VERBOSE, "nodeId = %d, subunitType = %d, " @@ -70,68 +55,36 @@ "functionBlockId = %d, addressType = %d, " "direction = %d, id = %d\n", - m_pConfigRom->getNodeId(), - m_subunitType, - m_subunitId, - m_functionBlockType, - m_functionBlockId, - m_addressType, - m_direction, - m_id ); -} - -AvPlug::AvPlug( const AvPlug& rhs ) - : m_p1394Service( rhs.m_p1394Service ) - , m_pConfigRom( rhs.m_pConfigRom ) - , m_subunitType( rhs.m_subunitType ) - , m_subunitId( rhs.m_subunitId ) - , m_functionBlockType( rhs.m_functionBlockType ) - , m_functionBlockId( rhs.m_functionBlockId ) - , m_addressType( rhs.m_addressType ) - , m_direction( rhs.m_direction ) - , m_id( rhs.m_id ) - , m_infoPlugType( rhs.m_infoPlugType ) - , m_nrOfChannels( rhs.m_nrOfChannels ) - , m_name( rhs.m_name ) - , m_clusterInfos( rhs.m_clusterInfos ) - , m_formatInfos( rhs.m_formatInfos ) - , m_plugManager( rhs.m_plugManager ) - , m_verboseLevel( rhs.m_verboseLevel ) -{ - if ( m_verboseLevel ) { - setDebugLevel( DEBUG_LEVEL_VERBOSE ); - } -} - -AvPlug::AvPlug() - : m_p1394Service( 0 ) - , m_pConfigRom( 0 ) - , m_subunitType( AVCCommand::eST_Reserved ) // a good value for unknown/undefined? - , m_subunitId( 0 ) - , m_functionBlockType( 0 ) - , m_functionBlockId( 0 ) - , m_addressType( eAPA_Undefined ) - , m_direction( eAPD_Unknown ) - , m_id( 0 ) - , m_infoPlugType( eAPT_Unknown ) - , m_nrOfChannels( 0 ) - , m_plugManager( 0 ) - , m_verboseLevel( 0 ) - , m_globalId( 0 ) -{ -} - -AvPlug::~AvPlug() -{ - if ( m_plugManager ) { - m_plugManager->remPlug( *this ); - } -} - -bool -AvPlug::discover() + unit->getConfigRom().getNodeId(), + getSubunitType(), + getSubunitId(), + functionBlockType, + functionBlockId, + plugAddressType, + plugDirection, + plugId ); +} + +Plug::Plug( const Plug& rhs ) + : AVC::Plug( rhs ) +{ + +} + +Plug::Plug() + : AVC::Plug() +{ +} + +Plug::~Plug() +{ + +} + +bool +Plug::discover() { if ( !discoverPlugType() ) { debugError( "discover: Could not discover plug type (%d,%d,%d,%d,%d)\n", - m_pConfigRom->getNodeId(), m_subunitType, m_subunitId, m_direction, m_id ); + m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id ); return false; } @@ -139,5 +92,5 @@ if ( !discoverName() ) { debugError( "Could not discover name (%d,%d,%d,%d,%d)\n", - m_pConfigRom->getNodeId(), m_subunitType, m_subunitId, m_direction, m_id ); + m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id ); return false; } @@ -146,5 +99,5 @@ debugError( "Could not discover number of channels " "(%d,%d,%d,%d,%d)\n", - m_pConfigRom->getNodeId(), m_subunitType, m_subunitId, m_direction, m_id ); + m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id ); return false; } @@ -153,5 +106,5 @@ debugError( "Could not discover channel positions " "(%d,%d,%d,%d,%d)\n", - m_pConfigRom->getNodeId(), m_subunitType, m_subunitId, m_direction, m_id ); + m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id ); return false; } @@ -160,5 +113,5 @@ debugError( "Could not discover channel name " "(%d,%d,%d,%d,%d)\n", - m_pConfigRom->getNodeId(), m_subunitType, m_subunitId, m_direction, m_id ); + m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id ); return false; } @@ -167,5 +120,5 @@ debugError( "Could not discover channel name " "(%d,%d,%d,%d,%d)\n", - m_pConfigRom->getNodeId(), m_subunitType, m_subunitId, m_direction, m_id ); + m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id ); return false; } @@ -174,5 +127,5 @@ debugError( "Could not discover stream format " "(%d,%d,%d,%d,%d)\n", - m_pConfigRom->getNodeId(), m_subunitType, m_subunitId, m_direction, m_id ); + m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id ); return false; } @@ -181,13 +134,13 @@ debugError( "Could not discover supported stream formats " "(%d,%d,%d,%d,%d)\n", - m_pConfigRom->getNodeId(), m_subunitType, m_subunitId, m_direction, m_id ); - return false; - } - - return m_plugManager->addPlug( *this ); -} - -bool -AvPlug::discoverConnections() + m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id ); + return false; + } + + return m_unit->getPlugManager().addPlug( *this ); +} + +bool +Plug::discoverConnections() { return discoverConnectionsInput() && discoverConnectionsOutput(); @@ -195,83 +148,5 @@ bool -AvPlug::inquireConnnection( AvPlug& plug ) -{ - SignalSourceCmd signalSourceCmd = setSrcPlugAddrToSignalCmd(); - setDestPlugAddrToSignalCmd( signalSourceCmd, plug ); - signalSourceCmd.setCommandType( AVCCommand::eCT_SpecificInquiry ); - signalSourceCmd.setVerbose( m_verboseLevel ); - - if ( !signalSourceCmd.fire() ) { - debugError( "Could not inquire connection between '%s' and '%s'\n", - getName(), plug.getName() ); - return false; - } - - if ( signalSourceCmd.getResponse() == AVCCommand::eR_Implemented ) { - debugOutput( DEBUG_LEVEL_VERBOSE, - "Connection possible between '%s' and '%s'\n", - getName(), plug.getName() ); - return true; - } - debugOutput( DEBUG_LEVEL_VERBOSE, - "Connection not possible between '%s' and '%s'\n", - getName(), plug.getName() ); - return false; -} - -bool -AvPlug::setConnection( AvPlug& plug ) -{ - SignalSourceCmd signalSourceCmd = setSrcPlugAddrToSignalCmd(); - setDestPlugAddrToSignalCmd( signalSourceCmd, plug ); - signalSourceCmd.setCommandType( AVCCommand::eCT_Control ); - signalSourceCmd.setVerbose( m_verboseLevel ); - - if ( !signalSourceCmd.fire() ) { - debugError( "Could not set connection between '%s' and '%s'\n", - getName(), plug.getName() ); - return false; - } - - if ( signalSourceCmd.getResponse() == AVCCommand::eR_Accepted ) { - debugOutput( DEBUG_LEVEL_VERBOSE, - "Could set connection between '%s' and '%s'\n", - getName(), plug.getName() ); - return true; - } - debugOutput( DEBUG_LEVEL_VERBOSE, - "Could not set connection between '%s' and '%s'\n", - getName(), plug.getName() ); - return false; -} - -int -AvPlug::getNrOfStreams() const -{ - int nrOfChannels = 0; - for ( ClusterInfoVector::const_iterator it = m_clusterInfos.begin(); - it != m_clusterInfos.end(); - ++it ) - { - const ClusterInfo* clusterInfo = &( *it ); - nrOfChannels += clusterInfo->m_nrOfChannels; - } - return nrOfChannels; -} - -int -AvPlug::getNrOfChannels() const -{ - return m_nrOfChannels; -} - -int -AvPlug::getSampleRate() const -{ - return convertESamplingFrequency( static_cast( m_samplingFrequency ) ); -} - -bool -AvPlug::discoverPlugType() +Plug::discoverPlugType() { ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd(); @@ -280,5 +155,5 @@ extendedPlugInfoInfoType.initialize(); extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType ); - extPlugInfoCmd.setVerbose( m_verboseLevel ); + extPlugInfoCmd.setVerbose( getDebugLevel() ); if ( !extPlugInfoCmd.fire() ) { @@ -336,5 +211,5 @@ bool -AvPlug::discoverName() +Plug::discoverName() { ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd(); @@ -343,5 +218,5 @@ extendedPlugInfoInfoType.initialize(); extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType ); - extPlugInfoCmd.setVerbose( m_verboseLevel ); + extPlugInfoCmd.setVerbose( getDebugLevel() ); if ( !extPlugInfoCmd.fire() ) { @@ -368,5 +243,5 @@ bool -AvPlug::discoverNoOfChannels() +Plug::discoverNoOfChannels() { ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd(); @@ -376,5 +251,5 @@ extendedPlugInfoInfoType.initialize(); extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType ); - extPlugInfoCmd.setVerbose( m_verboseLevel ); + extPlugInfoCmd.setVerbose( getDebugLevel() ); if ( !extPlugInfoCmd.fire() ) { @@ -401,5 +276,5 @@ bool -AvPlug::discoverChannelPosition() +Plug::discoverChannelPosition() { ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd(); @@ -408,5 +283,5 @@ extendedPlugInfoInfoType.initialize(); extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType ); - extPlugInfoCmd.setVerbose( m_verboseLevel ); + extPlugInfoCmd.setVerbose( getDebugLevel() ); if ( !extPlugInfoCmd.fire() ) { @@ -437,5 +312,50 @@ bool -AvPlug::discoverChannelName() +Plug::copyClusterInfo(ExtendedPlugInfoPlugChannelPositionSpecificData& + channelPositionData ) +{ + int index = 1; + for ( ExtendedPlugInfoPlugChannelPositionSpecificData::ClusterInfoVector::const_iterator it + = channelPositionData.m_clusterInfos.begin(); + it != channelPositionData.m_clusterInfos.end(); + ++it ) + { + const ExtendedPlugInfoPlugChannelPositionSpecificData::ClusterInfo* + extPlugSpClusterInfo = &( *it ); + + ClusterInfo clusterInfo; + clusterInfo.m_nrOfChannels = extPlugSpClusterInfo->m_nrOfChannels; + clusterInfo.m_index = index; + index++; + + for ( ExtendedPlugInfoPlugChannelPositionSpecificData::ChannelInfoVector::const_iterator cit + = extPlugSpClusterInfo->m_channelInfos.begin(); + cit != extPlugSpClusterInfo->m_channelInfos.end(); + ++cit ) + { + const ExtendedPlugInfoPlugChannelPositionSpecificData::ChannelInfo* + extPlugSpChannelInfo = &( *cit ); + + ChannelInfo channelInfo; + channelInfo.m_streamPosition = + extPlugSpChannelInfo->m_streamPosition-1; + // FIXME: this can only become a mess with the two meanings + // of the location parameter. the audio style meaning + // starts from 1, the midi style meaning from 0 + // lucky for us we recalculate this for the midi channels + // and don't use this value. + channelInfo.m_location = + extPlugSpChannelInfo->m_location; + + clusterInfo.m_channelInfos.push_back( channelInfo ); + } + m_clusterInfos.push_back( clusterInfo ); + } + + return true; +} + +bool +Plug::discoverChannelName() { for ( ClusterInfoVector::iterator clit = m_clusterInfos.begin(); @@ -456,5 +376,5 @@ extendedPlugInfoInfoType.initialize(); extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType ); - extPlugInfoCmd.setVerbose( m_verboseLevel ); + extPlugInfoCmd.setVerbose( getDebugLevel() ); ExtendedPlugInfoInfoType* infoType = @@ -489,5 +409,5 @@ bool -AvPlug::discoverClusterInfo() +Plug::discoverClusterInfo() { if ( m_infoPlugType == eAPT_Sync ) @@ -516,5 +436,5 @@ extendedPlugInfoInfoType.initialize(); extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType ); - extPlugInfoCmd.setVerbose( m_verboseLevel ); + extPlugInfoCmd.setVerbose( getDebugLevel() ); extPlugInfoCmd.getInfoType()->m_plugClusterInfo->m_clusterIndex = @@ -549,224 +469,5 @@ bool -AvPlug::discoverStreamFormat() -{ - ExtendedStreamFormatCmd extStreamFormatCmd = - setPlugAddrToStreamFormatCmd( ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommand ); - extStreamFormatCmd.setVerbose( m_verboseLevel ); - - if ( !extStreamFormatCmd.fire() ) { - debugError( "stream format command failed\n" ); - return false; - } - - if ( ( extStreamFormatCmd.getStatus() == ExtendedStreamFormatCmd::eS_NoStreamFormat ) - || ( extStreamFormatCmd.getStatus() == ExtendedStreamFormatCmd::eS_NotUsed ) ) - { - debugOutput( DEBUG_LEVEL_VERBOSE, - "No stream format information available\n" ); - return true; - } - - if ( !extStreamFormatCmd.getFormatInformation() ) { - debugWarning( "No stream format information for plug found -> skip\n" ); - return true; - } - - if ( extStreamFormatCmd.getFormatInformation()->m_root - != FormatInformation::eFHR_AudioMusic ) - { - debugWarning( "Format hierarchy root is not Audio&Music -> skip\n" ); - return true; - } - - FormatInformation* formatInfo = - extStreamFormatCmd.getFormatInformation(); - FormatInformationStreamsCompound* compoundStream - = dynamic_cast< FormatInformationStreamsCompound* > ( - formatInfo->m_streams ); - if ( compoundStream ) { - m_samplingFrequency = - compoundStream->m_samplingFrequency; - debugOutput( DEBUG_LEVEL_VERBOSE, - "%s plug %d uses " - "sampling frequency %d, nr of stream infos = %d\n", - getName(), - m_id, - m_samplingFrequency, - compoundStream->m_numberOfStreamFormatInfos ); - - for ( int i = 1; - i <= compoundStream->m_numberOfStreamFormatInfos; - ++i ) - { - ClusterInfo* clusterInfo = - const_cast( getClusterInfoByIndex( i ) ); - - if ( !clusterInfo ) { - debugError( "No matching cluster " - "info found for index %d\n", i ); - return false; - } - StreamFormatInfo* streamFormatInfo = - compoundStream->m_streamFormatInfos[ i - 1 ]; - - debugOutput( DEBUG_LEVEL_VERBOSE, - "number of channels = %d, stream format = %d\n", - streamFormatInfo->m_numberOfChannels, - streamFormatInfo->m_streamFormat ); - - int nrOfChannels = clusterInfo->m_nrOfChannels; - if ( streamFormatInfo->m_streamFormat == - FormatInformation::eFHL2_AM824_MIDI_CONFORMANT ) - { - // 8 logical midi channels fit into 1 channel - nrOfChannels = ( ( nrOfChannels + 7 ) / 8 ); - } - // sanity check - if ( nrOfChannels != streamFormatInfo->m_numberOfChannels ) - { - debugWarning( "Number of channels " - "mismatch: '%s' plug discovering reported " - "%d channels for cluster '%s', while stream " - "format reported %d\n", - getName(), - nrOfChannels, - clusterInfo->m_name.c_str(), - streamFormatInfo->m_numberOfChannels); - } - clusterInfo->m_streamFormat = streamFormatInfo->m_streamFormat; - - debugOutput( DEBUG_LEVEL_VERBOSE, - "%s plug %d cluster info %d ('%s'): " - "stream format %d\n", - getName(), - m_id, - i, - clusterInfo->m_name.c_str(), - clusterInfo->m_streamFormat ); - } - } - - FormatInformationStreamsSync* syncStream - = dynamic_cast< FormatInformationStreamsSync* > ( - formatInfo->m_streams ); - if ( syncStream ) { - m_samplingFrequency = - syncStream->m_samplingFrequency; - debugOutput( DEBUG_LEVEL_VERBOSE, - "%s plug %d is sync stream with sampling frequency %d\n", - getName(), - m_id, - m_samplingFrequency ); - } - - - if ( !compoundStream && !syncStream ) - { - debugError( "Unsupported stream format\n" ); - return false; - } - - return true; -} - -bool -AvPlug::discoverSupportedStreamFormats() -{ - ExtendedStreamFormatCmd extStreamFormatCmd = - setPlugAddrToStreamFormatCmd( - ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommandList); - extStreamFormatCmd.setVerbose( m_verboseLevel ); - - int i = 0; - bool cmdSuccess = false; - - do { - extStreamFormatCmd.setIndexInStreamFormat( i ); - extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status ); - cmdSuccess = extStreamFormatCmd.fire(); - if ( cmdSuccess - && ( extStreamFormatCmd.getResponse() - == AVCCommand::eR_Implemented ) ) - { - FormatInfo formatInfo; - formatInfo.m_index = i; - bool formatInfoIsValid = true; - - FormatInformationStreamsSync* syncStream - = dynamic_cast< FormatInformationStreamsSync* > - ( extStreamFormatCmd.getFormatInformation()->m_streams ); - if ( syncStream ) { - formatInfo.m_samplingFrequency = - syncStream->m_samplingFrequency; - formatInfo.m_isSyncStream = true ; - } - - FormatInformationStreamsCompound* compoundStream - = dynamic_cast< FormatInformationStreamsCompound* > - ( extStreamFormatCmd.getFormatInformation()->m_streams ); - if ( compoundStream ) { - formatInfo.m_samplingFrequency = - compoundStream->m_samplingFrequency; - formatInfo.m_isSyncStream = false; - for ( int j = 0; - j < compoundStream->m_numberOfStreamFormatInfos; - ++j ) - { - switch ( compoundStream->m_streamFormatInfos[j]->m_streamFormat ) { - case AVC1394_STREAM_FORMAT_AM824_IEC60968_3: - formatInfo.m_audioChannels += - compoundStream->m_streamFormatInfos[j]->m_numberOfChannels; - break; - case AVC1394_STREAM_FORMAT_AM824_MULTI_BIT_LINEAR_AUDIO_RAW: - formatInfo.m_audioChannels += - compoundStream->m_streamFormatInfos[j]->m_numberOfChannels; - break; - case AVC1394_STREAM_FORMAT_AM824_MIDI_CONFORMANT: - formatInfo.m_midiChannels += - compoundStream->m_streamFormatInfos[j]->m_numberOfChannels; - break; - default: - formatInfoIsValid = false; - debugWarning("unknown stream format (0x%02x) for channel " - "(%d)\n", - compoundStream->m_streamFormatInfos[j]->m_streamFormat, - j ); - } - } - } - - if ( formatInfoIsValid ) { - debugOutput( DEBUG_LEVEL_VERBOSE, - "[%s:%d] formatInfo[%d].m_samplingFrequency " - "= %d\n", - getName(), m_id, - i, formatInfo.m_samplingFrequency ); - debugOutput( DEBUG_LEVEL_VERBOSE, - "[%s:%d] formatInfo[%d].m_isSyncStream = %d\n", - getName(), m_id, - i, formatInfo.m_isSyncStream ); - debugOutput( DEBUG_LEVEL_VERBOSE, - "[%s:%d] formatInfo[%d].m_audioChannels = %d\n", - getName(), m_id, - i, formatInfo.m_audioChannels ); - debugOutput( DEBUG_LEVEL_VERBOSE, - "[%s:%d] formatInfo[%d].m_midiChannels = %d\n", - getName(), m_id, - i, formatInfo.m_midiChannels ); - m_formatInfos.push_back( formatInfo ); - } - } - - ++i; - } while ( cmdSuccess && ( extStreamFormatCmd.getResponse() - == ExtendedStreamFormatCmd::eR_Implemented ) ); - - return true; -} - - -bool -AvPlug::discoverConnectionsInput() +Plug::discoverConnectionsInput() { ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd(); @@ -775,5 +476,5 @@ extendedPlugInfoInfoType.initialize(); extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType ); - extPlugInfoCmd.setVerbose( m_verboseLevel ); + extPlugInfoCmd.setVerbose( getDebugLevel() ); if ( !extPlugInfoCmd.fire() ) { @@ -820,5 +521,5 @@ bool -AvPlug::discoverConnectionsOutput() +Plug::discoverConnectionsOutput() { ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd(); @@ -827,5 +528,5 @@ extendedPlugInfoInfoType.initialize(); extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType ); - extPlugInfoCmd.setVerbose( m_verboseLevel ); + extPlugInfoCmd.setVerbose( getDebugLevel() ); if ( !extPlugInfoCmd.fire() ) { @@ -883,75 +584,11 @@ } -bool -AvPlug::discoverConnectionsFromSpecificData( - EAvPlugDirection discoverDirection, - PlugAddressSpecificData* plugAddress, - AvPlugVector& connections ) -{ - UnitPlugSpecificDataPlugAddress* pUnitPlugAddress = - dynamic_cast - ( plugAddress->m_plugAddressData ); - - SubunitPlugSpecificDataPlugAddress* pSubunitPlugAddress = - dynamic_cast - ( plugAddress->m_plugAddressData ); - - FunctionBlockPlugSpecificDataPlugAddress* - pFunctionBlockPlugAddress = - dynamic_cast - ( plugAddress->m_plugAddressData ); - - AvPlug* plug = getPlugDefinedBySpecificData( - pUnitPlugAddress, - pSubunitPlugAddress, - pFunctionBlockPlugAddress ); - - if ( plug ) { - debugOutput( DEBUG_LEVEL_VERBOSE, - "'(%d) %s' has a connection to '(%d) %s'\n", - getGlobalId(), - getName(), - plug->getGlobalId(), - plug->getName() ); - addPlugConnection( connections, *plug ); - } else { - debugError( "no corresponding plug found for '(%d) %s'\n", - getGlobalId(), - getName() ); - return false; - } - - return true; -} - -bool -AvPlug::addPlugConnection( AvPlugVector& connections, - AvPlug& plug ) - -{ - for ( AvPlugVector::iterator it = connections.begin(); - it != connections.end(); - ++it ) - { - AvPlug* cPlug = *it; - if ( cPlug == &plug ) { - debugOutput( DEBUG_LEVEL_VERBOSE, - "plug '%s' already in connection list\n", - plug.getName() ); - return true; - } - } - - connections.push_back( &plug ); - return true; -} - ExtendedPlugInfoCmd -AvPlug::setPlugAddrToPlugInfoCmd() -{ - ExtendedPlugInfoCmd extPlugInfoCmd( *m_p1394Service ); - - switch( m_subunitType ) { - case AVCCommand::eST_Unit: +Plug::setPlugAddrToPlugInfoCmd() +{ + ExtendedPlugInfoCmd extPlugInfoCmd( m_unit->get1394Service() ); + + switch( getSubunitType() ) { + case eST_Unit: { UnitPlugAddress::EPlugType ePlugType = @@ -978,6 +615,6 @@ } break; - case AVCCommand::eST_Music: - case AVCCommand::eST_Audio: + case eST_Music: + case eST_Audio: { switch( m_addressType ) { @@ -1014,1237 +651,11 @@ } - extPlugInfoCmd.setNodeId( m_pConfigRom->getNodeId() ); + extPlugInfoCmd.setNodeId( m_unit->getConfigRom().getNodeId() ); extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status ); - extPlugInfoCmd.setSubunitId( m_subunitId ); - extPlugInfoCmd.setSubunitType( m_subunitType ); + extPlugInfoCmd.setSubunitId( getSubunitId() ); + extPlugInfoCmd.setSubunitType( getSubunitType() ); return extPlugInfoCmd; } -ExtendedStreamFormatCmd -AvPlug::setPlugAddrToStreamFormatCmd( - ExtendedStreamFormatCmd::ESubFunction subFunction) -{ - ExtendedStreamFormatCmd extStreamFormatInfoCmd( - *m_p1394Service, - subFunction ); - switch( m_subunitType ) { - case AVCCommand::eST_Unit: - { - UnitPlugAddress::EPlugType ePlugType = - UnitPlugAddress::ePT_Unknown; - switch ( m_addressType ) { - case eAPA_PCR: - ePlugType = UnitPlugAddress::ePT_PCR; - break; - case eAPA_ExternalPlug: - ePlugType = UnitPlugAddress::ePT_ExternalPlug; - break; - case eAPA_AsynchronousPlug: - ePlugType = UnitPlugAddress::ePT_AsynchronousPlug; - break; - default: - ePlugType = UnitPlugAddress::ePT_Unknown; - } - UnitPlugAddress unitPlugAddress( ePlugType, - m_id ); - extStreamFormatInfoCmd.setPlugAddress( - PlugAddress( convertPlugDirection( getPlugDirection() ), - PlugAddress::ePAM_Unit, - unitPlugAddress ) ); - } - break; - case AVCCommand::eST_Music: - case AVCCommand::eST_Audio: - { - switch( m_addressType ) { - case eAPA_SubunitPlug: - { - SubunitPlugAddress subunitPlugAddress( m_id ); - extStreamFormatInfoCmd.setPlugAddress( - PlugAddress( convertPlugDirection( getPlugDirection() ), - PlugAddress::ePAM_Subunit, - subunitPlugAddress ) ); - } - break; - case eAPA_FunctionBlockPlug: - { - FunctionBlockPlugAddress functionBlockPlugAddress( - m_functionBlockType, - m_functionBlockId, - m_id ); - extStreamFormatInfoCmd.setPlugAddress( - PlugAddress( convertPlugDirection( getPlugDirection() ), - PlugAddress::ePAM_FunctionBlock, - functionBlockPlugAddress ) ); - } - break; - default: - extStreamFormatInfoCmd.setPlugAddress(PlugAddress()); - } - } - break; - default: - debugError( "Unknown subunit type\n" ); - } - - extStreamFormatInfoCmd.setNodeId( m_pConfigRom->getNodeId() ); - extStreamFormatInfoCmd.setCommandType( AVCCommand::eCT_Status ); - extStreamFormatInfoCmd.setSubunitId( m_subunitId ); - extStreamFormatInfoCmd.setSubunitType( m_subunitType ); - - return extStreamFormatInfoCmd; -} - -SignalSourceCmd -AvPlug::setSrcPlugAddrToSignalCmd() -{ - SignalSourceCmd signalSourceCmd( *m_p1394Service ); - - switch( m_subunitType ) { - case AVCCommand::eST_Unit: - { - SignalUnitAddress signalUnitAddr; - if ( getPlugAddressType() == eAPA_ExternalPlug ) { - signalUnitAddr.m_plugId = m_id + 0x80; - } else { - signalUnitAddr.m_plugId = m_id; - } - signalSourceCmd.setSignalSource( signalUnitAddr ); - } - break; - case AVCCommand::eST_Music: - case AVCCommand::eST_Audio: - { - SignalSubunitAddress signalSubunitAddr; - signalSubunitAddr.m_subunitType = m_subunitType; - signalSubunitAddr.m_subunitId = m_subunitId; - signalSubunitAddr.m_plugId = m_id; - signalSourceCmd.setSignalSource( signalSubunitAddr ); - } - break; - default: - debugError( "Unknown subunit type\n" ); - } - - signalSourceCmd.setNodeId( m_pConfigRom->getNodeId() ); - signalSourceCmd.setSubunitType( AVCCommand::eST_Unit ); - signalSourceCmd.setSubunitId( 0xff ); - - return signalSourceCmd; -} - -void -AvPlug::setDestPlugAddrToSignalCmd(SignalSourceCmd& signalSourceCmd, - AvPlug& plug) -{ - switch( plug.m_subunitType ) { - case AVCCommand::eST_Unit: - { - SignalUnitAddress signalUnitAddr; - if ( plug.getPlugAddressType() == eAPA_ExternalPlug ) { - signalUnitAddr.m_plugId = plug.m_id + 0x80; - } else { - signalUnitAddr.m_plugId = plug.m_id; - } - signalSourceCmd.setSignalDestination( signalUnitAddr ); - } - break; - case AVCCommand::eST_Music: - case AVCCommand::eST_Audio: - { - SignalSubunitAddress signalSubunitAddr; - signalSubunitAddr.m_subunitType = plug.m_subunitType; - signalSubunitAddr.m_subunitId = plug.m_subunitId; - signalSubunitAddr.m_plugId = plug.m_id; - signalSourceCmd.setSignalDestination( signalSubunitAddr ); - } - break; - default: - debugError( "Unknown subunit type\n" ); - } -} - - -bool -AvPlug::copyClusterInfo(ExtendedPlugInfoPlugChannelPositionSpecificData& - channelPositionData ) -{ - int index = 1; - for ( ExtendedPlugInfoPlugChannelPositionSpecificData::ClusterInfoVector::const_iterator it - = channelPositionData.m_clusterInfos.begin(); - it != channelPositionData.m_clusterInfos.end(); - ++it ) - { - const ExtendedPlugInfoPlugChannelPositionSpecificData::ClusterInfo* - extPlugSpClusterInfo = &( *it ); - - ClusterInfo clusterInfo; - clusterInfo.m_nrOfChannels = extPlugSpClusterInfo->m_nrOfChannels; - clusterInfo.m_index = index; - index++; - - for ( ExtendedPlugInfoPlugChannelPositionSpecificData::ChannelInfoVector::const_iterator cit - = extPlugSpClusterInfo->m_channelInfos.begin(); - cit != extPlugSpClusterInfo->m_channelInfos.end(); - ++cit ) - { - const ExtendedPlugInfoPlugChannelPositionSpecificData::ChannelInfo* - extPlugSpChannelInfo = &( *cit ); - - ChannelInfo channelInfo; - channelInfo.m_streamPosition = - extPlugSpChannelInfo->m_streamPosition; - channelInfo.m_location = - extPlugSpChannelInfo->m_location; - - clusterInfo.m_channelInfos.push_back( channelInfo ); - } - m_clusterInfos.push_back( clusterInfo ); - } - - return true; -} - -void -AvPlug::debugOutputClusterInfos( int debugLevel ) -{ - for ( ClusterInfoVector::const_iterator it = m_clusterInfos.begin(); - it != m_clusterInfos.end(); - ++it ) - { - const ClusterInfo* clusterInfo = &( *it ); - - debugOutput( debugLevel, "number of channels: %d\n", - clusterInfo->m_nrOfChannels ); - - for ( ChannelInfoVector::const_iterator cit - = clusterInfo->m_channelInfos.begin(); - cit != clusterInfo->m_channelInfos.end(); - ++cit ) - { - const ChannelInfo* channelInfo = &( *cit ); - channelInfo = channelInfo; - debugOutput( debugLevel, - "stream position: %d\n", - channelInfo->m_streamPosition ); - debugOutput( debugLevel, - "location: %d\n", - channelInfo->m_location ); - } - } -} - -const AvPlug::ClusterInfo* -AvPlug::getClusterInfoByIndex(int index) const -{ - for ( AvPlug::ClusterInfoVector::const_iterator clit = - m_clusterInfos.begin(); - clit != m_clusterInfos.end(); - ++clit ) - { - const ClusterInfo* info = &*clit; - if ( info->m_index == index ) { - return info; - } - } - return 0; -} - -PlugAddress::EPlugDirection -AvPlug::convertPlugDirection( EAvPlugDirection direction ) -{ - PlugAddress::EPlugDirection dir; - switch ( direction ) { - case AvPlug::eAPD_Input: - dir = PlugAddress::ePD_Input; - break; - case AvPlug::eAPD_Output: - dir = PlugAddress::ePD_Output; - break; - default: - dir = PlugAddress::ePD_Undefined; - } - return dir; -} - -void -AvPlug::showPlug() const -{ - debugOutput( DEBUG_LEVEL_VERBOSE, "\tName = %s\n", - getName() ); - debugOutput( DEBUG_LEVEL_VERBOSE, "\tType = %s\n", - extendedPlugInfoPlugTypeToString( getPlugType() ) ); - debugOutput( DEBUG_LEVEL_VERBOSE, "\tAddress Type = %s\n", - avPlugAddressTypeToString( getPlugAddressType() ) ); - debugOutput( DEBUG_LEVEL_VERBOSE, "\tId = %d\n", - getPlugId() ); - debugOutput( DEBUG_LEVEL_VERBOSE, "\tSubunitType = %d\n", - getSubunitType() ); - debugOutput( DEBUG_LEVEL_VERBOSE, "\tSubunitId = %d\n", - getSubunitId() ); - debugOutput( DEBUG_LEVEL_VERBOSE, "\tDirection = %s\n", - avPlugDirectionToString( getPlugDirection() ) ); - debugOutput( DEBUG_LEVEL_VERBOSE, "\tSampling Rate = %d\n", - getSampleRate() ); - debugOutput( DEBUG_LEVEL_VERBOSE, "\tNumber of Channels = %d\n", - getNrOfChannels() ); - debugOutput( DEBUG_LEVEL_VERBOSE, "\tNumber of Streams = %d\n", - getNrOfStreams() ); -} - - -AvPlug* -AvPlug::getPlugDefinedBySpecificData( - UnitPlugSpecificDataPlugAddress* pUnitPlugAddress, - SubunitPlugSpecificDataPlugAddress* pSubunitPlugAddress, - FunctionBlockPlugSpecificDataPlugAddress* pFunctionBlockPlugAddress ) -{ - subunit_type_t subunitType = 0xff; - subunit_id_t subunitId = 0xff; - function_block_type_t functionBlockType = 0xff; - function_block_id_t functionBlockId = 0xff; - EAvPlugAddressType addressType = eAPA_Undefined; - EAvPlugDirection direction = eAPD_Unknown; - plug_id_t plugId = 0xff; - - if ( !pUnitPlugAddress - && !pSubunitPlugAddress - && !pFunctionBlockPlugAddress ) - { - debugError( "No correct specific data found\n" ); - return 0; - } - - if ( pUnitPlugAddress ) { - subunitType = AVCCommand::eST_Unit; - switch ( pUnitPlugAddress->m_plugType ) { - case UnitPlugSpecificDataPlugAddress::ePT_PCR: - addressType = eAPA_PCR; - break; - case UnitPlugSpecificDataPlugAddress::ePT_ExternalPlug: - addressType = eAPA_ExternalPlug; - break; - case UnitPlugSpecificDataPlugAddress::ePT_AsynchronousPlug: - addressType = eAPA_AsynchronousPlug; - break; - } - // unit plug have only connections to subunits - if ( getPlugAddressType() == eAPA_SubunitPlug ) { - direction = getDirection(); - } else { - debugError( "Function block has connection from/to unknown " - "plug type\n" ); - direction = eAPD_Unknown; - } - plugId = pUnitPlugAddress->m_plugId; - - debugOutput( DEBUG_LEVEL_VERBOSE, - "'(%d) %s': Remote plug is a unit plug " - "(%s, %s, %d)\n", - getGlobalId(), - getName(), - avPlugAddressTypeToString( addressType ), - avPlugDirectionToString( direction ), - plugId ); - } - - if ( pSubunitPlugAddress ) { - subunitType = pSubunitPlugAddress->m_subunitType; - subunitId = pSubunitPlugAddress->m_subunitId; - addressType = eAPA_SubunitPlug; - - if ( getPlugAddressType() == eAPA_FunctionBlockPlug ) { - direction = getDirection(); - } else if ( getPlugAddressType() == eAPA_SubunitPlug ) { - direction = toggleDirection( getDirection() ); - } else { - // unit - direction = getDirection(); - } - - plugId = pSubunitPlugAddress->m_plugId; - debugOutput( DEBUG_LEVEL_VERBOSE, - "'(%d) %s': Remote plug is a subunit plug " - "(%d, %d, %s, %d)\n", - getGlobalId(), - getName(), - subunitType, - subunitId, - avPlugDirectionToString( direction ), - plugId ); - } - - if ( pFunctionBlockPlugAddress ) { - subunitType = pFunctionBlockPlugAddress->m_subunitType; - subunitId = pFunctionBlockPlugAddress->m_subunitId; - functionBlockType = pFunctionBlockPlugAddress->m_functionBlockType; - functionBlockId = pFunctionBlockPlugAddress->m_functionBlockId; - addressType = eAPA_FunctionBlockPlug; - - if ( getPlugAddressType() == eAPA_FunctionBlockPlug ) { - direction = toggleDirection( getDirection() ); - } else if ( getPlugAddressType() == eAPA_SubunitPlug ){ - direction = getDirection(); - } else { - debugError( "Function block has connection from/to unknown " - "plug type\n" ); - direction = eAPD_Unknown; - } - - plugId = pFunctionBlockPlugAddress->m_plugId; - - debugOutput( DEBUG_LEVEL_VERBOSE, - "'(%d) %s': Remote plug is a functionblock plug " - "(%d, %d, %d, %d, %s, %d)\n", - getGlobalId(), - getName(), - subunitType, - subunitId, - functionBlockType, - functionBlockId, - avPlugDirectionToString( direction ), - plugId ); - } - - AVCCommand::ESubunitType enumSubunitType = - static_cast( subunitType ); - - return m_plugManager->getPlug( - enumSubunitType, - subunitId, - functionBlockType, - functionBlockId, - addressType, - direction, - plugId ); -} - -AvPlug::EAvPlugDirection -AvPlug::toggleDirection( EAvPlugDirection direction ) const -{ - EAvPlugDirection newDirection; - switch ( direction ) { - case eAPD_Output: - newDirection = eAPD_Input; - break; - case eAPD_Input: - newDirection = eAPD_Output; - break; - default: - newDirection = direction; - } - - return newDirection; -} - -bool -AvPlug::serializeChannelInfos( Glib::ustring basePath, - Util::IOSerialize& ser, - const ClusterInfo& clusterInfo ) const -{ - bool result = true; - int i = 0; - for ( ChannelInfoVector::const_iterator it = clusterInfo.m_channelInfos.begin(); - it != clusterInfo.m_channelInfos.end(); - ++it ) - { - const ChannelInfo& info = *it; - std::ostringstream strstrm; - strstrm << basePath << i; - - result &= ser.write( strstrm.str() + "/m_streamPosition", info.m_streamPosition ); - result &= ser.write( strstrm.str() + "/m_location", info.m_location ); - result &= ser.write( strstrm.str() + "/m_name", info.m_name ); - } - - return result; -} - -bool -AvPlug::deserializeChannelInfos( Glib::ustring basePath, - Util::IODeserialize& deser, - ClusterInfo& clusterInfo ) -{ - int i = 0; - bool bFinished = false; - bool result = true; - do { - std::ostringstream strstrm; - strstrm << basePath << i; - - // check for one element to exist. when one exist the other elements - // must also be there. otherwise just return (last) result. - if ( deser.isExisting( strstrm.str() + "/m_streamPosition" ) ) { - ChannelInfo info; - - result &= deser.read( strstrm.str() + "/m_streamPosition", info.m_streamPosition ); - result &= deser.read( strstrm.str() + "/m_location", info.m_location ); - result &= deser.read( strstrm.str() + "/m_name", info.m_name ); - - if ( result ) { - clusterInfo.m_channelInfos.push_back( info ); - i++; - } else { - bFinished = true; - } - } else { - bFinished = true; - } - } while ( !bFinished ); - - return result; -} - - -bool -AvPlug::serializeClusterInfos( Glib::ustring basePath, - Util::IOSerialize& ser ) const -{ - bool result = true; - int i = 0; - for ( ClusterInfoVector::const_iterator it = m_clusterInfos.begin(); - it != m_clusterInfos.end(); - ++it ) - { - const ClusterInfo& info = *it; - std::ostringstream strstrm; - strstrm << basePath << i; - - result &= ser.write( strstrm.str() + "/m_index", info.m_index ); - result &= ser.write( strstrm.str() + "/m_portType", info.m_portType ); - result &= ser.write( strstrm.str() + "/m_name", info.m_name ); - result &= ser.write( strstrm.str() + "/m_nrOfChannels", info.m_nrOfChannels ); - result &= serializeChannelInfos( strstrm.str() + "/m_channelInfo", ser, info ); - result &= ser.write( strstrm.str() + "/m_streamFormat", info.m_streamFormat ); - - } - - return result; -} - -bool -AvPlug::deserializeClusterInfos( Glib::ustring basePath, - Util::IODeserialize& deser ) -{ - int i = 0; - bool bFinished = false; - bool result = true; - do { - std::ostringstream strstrm; - strstrm << basePath << i; - - // check for one element to exist. when one exist the other elements - // must also be there. otherwise just return (last) result. - if ( deser.isExisting( strstrm.str() + "/m_index" ) ) { - ClusterInfo info; - - result &= deser.read( strstrm.str() + "/m_index", info.m_index ); - result &= deser.read( strstrm.str() + "/m_portType", info.m_portType ); - result &= deser.read( strstrm.str() + "/m_name", info.m_name ); - result &= deser.read( strstrm.str() + "/m_nrOfChannels", info.m_nrOfChannels ); - result &= deserializeChannelInfos( strstrm.str() + "/m_channelInfo", deser, info ); - result &= deser.read( strstrm.str() + "/m_streamFormat", info.m_streamFormat ); - - if ( result ) { - m_clusterInfos.push_back( info ); - i++; - } else { - bFinished = true; - } - } else { - bFinished = true; - } - } while ( !bFinished ); - - return result; -} - - -bool -AvPlug::serializeFormatInfos( Glib::ustring basePath, - Util::IOSerialize& ser ) const -{ - bool result = true; - int i = 0; - for ( FormatInfoVector::const_iterator it = m_formatInfos.begin(); - it != m_formatInfos.end(); - ++it ) - { - const FormatInfo& info = *it; - std::ostringstream strstrm; - strstrm << basePath << i; - - result &= ser.write( strstrm.str() + "/m_samplingFrequency", info.m_samplingFrequency ); - result &= ser.write( strstrm.str() + "/m_isSyncStream", info.m_isSyncStream ); - result &= ser.write( strstrm.str() + "/m_audioChannels", info.m_audioChannels ); - result &= ser.write( strstrm.str() + "/m_midiChannels", info.m_midiChannels ); - result &= ser.write( strstrm.str() + "/m_index", info.m_index ); - } - return result; -} - -bool -AvPlug::deserializeFormatInfos( Glib::ustring basePath, - Util::IODeserialize& deser ) -{ - int i = 0; - bool bFinished = false; - bool result = true; - do { - std::ostringstream strstrm; - strstrm << basePath << i; - - // check for one element to exist. when one exist the other elements - // must also be there. otherwise just return (last) result. - if ( deser.isExisting( strstrm.str() + "/m_samplingFrequency" ) ) { - FormatInfo info; - - result &= deser.read( strstrm.str() + "/m_samplingFrequency", info.m_samplingFrequency ); - result &= deser.read( strstrm.str() + "/m_isSyncStream", info.m_isSyncStream ); - result &= deser.read( strstrm.str() + "/m_audioChannels", info.m_audioChannels ); - result &= deser.read( strstrm.str() + "/m_midiChannels", info.m_midiChannels ); - result &= deser.read( strstrm.str() + "/m_index", info.m_index ); - - if ( result ) { - m_formatInfos.push_back( info ); - i++; - } else { - bFinished = true; - } - } else { - bFinished = true; - } - } while ( !bFinished ); - - return result; -} - - -bool -AvPlug::serializeAvPlugVector( Glib::ustring basePath, - Util::IOSerialize& ser, - const AvPlugVector& vec) const -{ - bool result = true; - int i = 0; - for ( AvPlugVector::const_iterator it = vec.begin(); - it != vec.end(); - ++it ) - { - const AvPlug* pPlug = *it; - std::ostringstream strstrm; - strstrm << basePath << i; - - result &= ser.write( strstrm.str() + "/global_id", pPlug->getGlobalId() ); - i++; - } - return result; -} - -bool -AvPlug::deserializeAvPlugVector( Glib::ustring basePath, - Util::IODeserialize& deser, - AvPlugVector& vec ) -{ - int i = 0; - bool bFinished = false; - bool result = true; - do { - std::ostringstream strstrm; - strstrm << basePath << i; - - // check for one element to exist. when one exist the other elements - // must also be there. otherwise just return (last) result. - if ( deser.isExisting( strstrm.str() + "/global_id" ) ) { - unsigned int iPlugId; - result &= deser.read( strstrm.str() + "/global_id", iPlugId ); - - if ( result ) { - AvPlug* pPlug = m_plugManager->getPlug( iPlugId ); - if ( pPlug ) { - vec.push_back( pPlug ); - } else { - result = false; - bFinished = true; - } - i++; - } else { - bFinished = true; - } - } else { - bFinished = true; - } - } while ( !bFinished ); - - return result; -} - -bool -AvPlug::serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const -{ - bool result; - result = ser.write( basePath + "m_subunitType", m_subunitType ); - result &= ser.write( basePath + "m_subunitId", m_subunitId ); - result &= ser.write( basePath + "m_functionBlockType", m_functionBlockType); - result &= ser.write( basePath + "m_functionBlockId", m_functionBlockId); - result &= ser.write( basePath + "m_addressType", m_addressType ); - result &= ser.write( basePath + "m_direction", m_direction); - result &= ser.write( basePath + "m_id", m_id); - result &= ser.write( basePath + "m_infoPlugType", m_infoPlugType); - result &= ser.write( basePath + "m_nrOfChannels", m_nrOfChannels); - result &= ser.write( basePath + "m_name", m_name); - result &= serializeClusterInfos( basePath + "m_clusterInfos", ser ); - result &= ser.write( basePath + "m_samplingFrequency", m_samplingFrequency); - result &= serializeFormatInfos( basePath + "m_formatInfo", ser ); - result &= serializeAvPlugVector( basePath + "m_inputConnections", ser, m_inputConnections ); - result &= serializeAvPlugVector( basePath + "m_outputConnections", ser, m_outputConnections ); - result &= ser.write( basePath + "m_verboseLevel", m_verboseLevel); - result &= ser.write( basePath + "m_globalId", m_globalId); - result &= ser.write( basePath + "m_globalIdCounter", m_globalIdCounter ); - - return result; -} - -AvPlug* -AvPlug::deserialize( Glib::ustring basePath, - Util::IODeserialize& deser, - AvDevice& avDevice, - AvPlugManager& plugManager ) -{ - if ( !deser.isExisting( basePath + "m_subunitType" ) ) { - return 0; - } - - AvPlug* pPlug = new AvPlug; - if ( !pPlug ) { - return 0; - } - - pPlug->m_p1394Service = &avDevice.get1394Service(); - pPlug->m_pConfigRom = &avDevice.getConfigRom(); - pPlug->m_plugManager = &plugManager; - bool result; - result = deser.read( basePath + "m_subunitType", pPlug->m_subunitType ); - result &= deser.read( basePath + "m_subunitId", pPlug->m_subunitId ); - result &= deser.read( basePath + "m_functionBlockType", pPlug->m_functionBlockType ); - result &= deser.read( basePath + "m_functionBlockId", pPlug->m_functionBlockId ); - result &= deser.read( basePath + "m_addressType", pPlug->m_addressType ); - result &= deser.read( basePath + "m_direction", pPlug->m_direction ); - result &= deser.read( basePath + "m_id", pPlug->m_id ); - result &= deser.read( basePath + "m_infoPlugType", pPlug->m_infoPlugType ); - result &= deser.read( basePath + "m_nrOfChannels", pPlug->m_nrOfChannels ); - result &= deser.read( basePath + "m_name", pPlug->m_name ); - result &= pPlug->deserializeClusterInfos( basePath + "m_clusterInfos", deser ); - result &= deser.read( basePath + "m_samplingFrequency", pPlug->m_samplingFrequency ); - result &= pPlug->deserializeFormatInfos( basePath + "m_formatInfos", deser ); - // input and output connections can't be processed here because not all plugs might - // deserialized at this point. so we do that in deserializeUpdate. - result &= deser.read( basePath + "m_verboseLevel", pPlug->m_verboseLevel ); - result &= deser.read( basePath + "m_globalId", pPlug->m_globalId ); - result &= deser.read( basePath + "m_globalIdCounter", pPlug->m_globalIdCounter ); - - if ( !result ) { - delete pPlug; - return 0; - } - - return pPlug; -} - -bool -AvPlug::deserializeUpdate( Glib::ustring basePath, - Util::IODeserialize& deser ) -{ - bool result; - - result = deserializeAvPlugVector( basePath + "m_inputConnections", deser, m_inputConnections ); - result &= deserializeAvPlugVector( basePath + "m_outputConnections", deser, m_outputConnections ); - - return result; -} - -///////////////////////////////////////// -///////////////////////////////////////// - -const char* avPlugAddressTypeStrings[] = -{ - "PCR", - "external", - "asynchronous", - "subunit", - "functionblock", - "undefined", -}; - -const char* avPlugAddressTypeToString( AvPlug::EAvPlugAddressType type ) -{ - if ( type > ( int )( sizeof( avPlugAddressTypeStrings ) - / sizeof( avPlugAddressTypeStrings[0] ) ) ) - { - type = AvPlug::eAPA_Undefined; - } - return avPlugAddressTypeStrings[type]; -} - -const char* avPlugTypeStrings[] = -{ - "IsoStream", - "AsyncStream", - "MIDI", - "Sync", - "Analog", - "Digital", - "Unknown", -}; - -const char* avPlugTypeToString( AvPlug::EAvPlugType type ) -{ - if ( type > ( int )( sizeof( avPlugTypeStrings ) - / sizeof( avPlugTypeStrings[0] ) ) ) - { - type = AvPlug::eAPT_Unknown; - } - return avPlugTypeStrings[type]; -} - -const char* avPlugDirectionStrings[] = -{ - "Input", - "Output", - "Unknown", -}; - -const char* avPlugDirectionToString( AvPlug::EAvPlugDirection type ) -{ - if ( type > ( int )( sizeof( avPlugDirectionStrings ) - / sizeof( avPlugDirectionStrings[0] ) ) ) - { - type = AvPlug::eAPD_Unknown; - } - return avPlugDirectionStrings[type]; -} - -///////////////////////////////////// - - -AvPlugManager::AvPlugManager( int verboseLevel ) - : m_verboseLevel( verboseLevel ) -{ - setDebugLevel( m_verboseLevel ); -} - -AvPlugManager::AvPlugManager() - : m_verboseLevel( 0 ) -{ - setDebugLevel( 0 ); -} - -AvPlugManager::AvPlugManager( const AvPlugManager& rhs ) - : m_verboseLevel( rhs.m_verboseLevel ) -{ - setDebugLevel( m_verboseLevel ); -} - -AvPlugManager::~AvPlugManager() -{ -} - -bool -AvPlugManager::addPlug( AvPlug& plug ) -{ - m_plugs.push_back( &plug ); - return true; -} - -bool -AvPlugManager::remPlug( AvPlug& plug ) -{ - for ( AvPlugVector::iterator it = m_plugs.begin(); - it != m_plugs.end(); - ++it ) - { - AvPlug* plugIt = *it; - if ( plugIt == &plug ) { - m_plugs.erase( it ); - return true; - } - } - return false; -} - -// helper function -static void addConnection( AvPlugConnectionOwnerVector& connections, - AvPlug& srcPlug, - AvPlug& destPlug ) -{ - for ( AvPlugConnectionOwnerVector::iterator it = connections.begin(); - it != connections.end(); - ++it ) - { - AvPlugConnection& con = *it; - if ( ( &( con.getSrcPlug() ) == &srcPlug ) - && ( &( con.getDestPlug() ) == &destPlug ) ) - { - return; - } - } - connections.push_back( AvPlugConnection( srcPlug, destPlug ) ); -} - -void -AvPlugManager::showPlugs() const -{ - // \todo The information provided here could be better arranged. For a start it is ok, but - // there is room for improvement. Something for a lazy sunday afternoon (tip: maybe drink some - // beer to get into the mood) - - printf( "\nSummary\n" ); - printf( "-------\n\n" ); - printf( "Nr | AddressType | Direction | SubUnitType | SubUnitId | FunctionBlockType | FunctionBlockId | Id | Type |Name\n" ); - printf( "---+-----------------+-----------+-------------+-----------+-------------------+-----------------+------+--------------+------\n" ); - - for ( AvPlugVector::const_iterator it = m_plugs.begin(); - it != m_plugs.end(); - ++it ) - { - AvPlug* plug = *it; - - printf( "%2d | %15s | %9s | %11s | 0x%02x | 0x%02x | 0x%02x | 0x%02x | %12s | %s\n", - plug->getGlobalId(), - avPlugAddressTypeToString( plug->getPlugAddressType() ), - avPlugDirectionToString( plug->getDirection() ), - subunitTypeToString( plug->getSubunitType() ), - plug->getSubunitId(), - plug->getFunctionBlockType(), - plug->getFunctionBlockId(), - plug->getPlugId(), - avPlugTypeToString( plug->getPlugType() ), - plug->getName() ); - } - - printf( "\nConnections\n" ); - printf( "-----------\n" ); - - AvPlugConnectionOwnerVector connections; - - for ( AvPlugVector::const_iterator it = m_plugs.begin(); - it != m_plugs.end(); - ++it ) - { - AvPlug* plug = *it; - for ( AvPlugVector::const_iterator it = - plug->getInputConnections().begin(); - it != plug->getInputConnections().end(); - ++it ) - { - addConnection( connections, *( *it ), *plug ); - } - for ( AvPlugVector::const_iterator it = - plug->getOutputConnections().begin(); - it != plug->getOutputConnections().end(); - ++it ) - { - addConnection( connections, *plug, *( *it ) ); - } - } - - printf( "digraph avcconnections {\n" ); - for ( AvPlugConnectionOwnerVector::iterator it = connections.begin(); - it != connections.end(); - ++it ) - { - AvPlugConnection& con = *it; - printf( "\t\"(%d) %s\" -> \"(%d) %s\"\n", - con.getSrcPlug().getGlobalId(), - con.getSrcPlug().getName(), - con.getDestPlug().getGlobalId(), - con.getDestPlug().getName() ); - } - for ( AvPlugVector::const_iterator it = m_plugs.begin(); - it != m_plugs.end(); - ++it ) - { - AvPlug* plug = *it; - if ( plug->getFunctionBlockType() != 0xff ) { - std::ostringstream strstrm; - switch(plug->getFunctionBlockType()) { - case 0x80: - strstrm << "Selector FB"; - break; - case 0x81: - strstrm << "Feature FB"; - break; - case 0x82: - strstrm << "Processing FB"; - break; - case 0x83: - strstrm << "CODEC FB"; - break; - default: - strstrm << plug->getFunctionBlockType(); - } - - if ( plug->getPlugDirection() == AvPlug::eAPD_Input ) { - printf( "\t\"(%d) %s\" -> \"(%s, ID %d)\"\n", - plug->getGlobalId(), - plug->getName(), - strstrm.str().c_str(), - plug->getFunctionBlockId() ); - } else { - printf( "\t\"(%s, ID %d)\" -> \t\"(%d) %s\"\n", - strstrm.str().c_str(), - plug->getFunctionBlockId(), - plug->getGlobalId(), - plug->getName() ); - } - } - } - - const char* colorStrings[] = { - "coral", - "slateblue", - "white", - "green", - "yellow", - "grey", - }; - - for ( AvPlugVector::const_iterator it = m_plugs.begin(); - it != m_plugs.end(); - ++it ) - { - AvPlug* plug = *it; - printf( "\t\"(%d) %s\" [color=%s,style=filled];\n", - plug->getGlobalId(), plug->getName(), - colorStrings[plug->getPlugAddressType() ] ); - } - - printf("}\n" ); - printf( "Use \"dot -Tps FILENAME.dot -o FILENAME.ps\" " - "to generate graph\n"); - - debugOutput( DEBUG_LEVEL_VERBOSE, "Plug details\n" ); - debugOutput( DEBUG_LEVEL_VERBOSE, "------------\n" ); - for ( AvPlugVector::const_iterator it = m_plugs.begin(); - it != m_plugs.end(); - ++it ) - { - AvPlug* plug = *it; - debugOutput( DEBUG_LEVEL_VERBOSE, "Plug %d:\n", plug->getGlobalId() ); - plug->showPlug(); - - } -} - -AvPlug* -AvPlugManager::getPlug( AVCCommand::ESubunitType subunitType, - subunit_id_t subunitId, - function_block_type_t functionBlockType, - function_block_id_t functionBlockId, - AvPlug::EAvPlugAddressType plugAddressType, - AvPlug::EAvPlugDirection plugDirection, - plug_id_t plugId ) const -{ - debugOutput( DEBUG_LEVEL_VERBOSE, "SBT, SBID, FBT, FBID, AT, PD, ID = " - "(0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x)\n", - subunitType, - subunitId, - functionBlockType, - functionBlockId, - plugAddressType, - plugDirection, - plugId ); - - for ( AvPlugVector::const_iterator it = m_plugs.begin(); - it != m_plugs.end(); - ++it ) - { - AvPlug* plug = *it; - - if ( ( subunitType == plug->getSubunitType() ) - && ( subunitId == plug->getSubunitId() ) - && ( functionBlockType == plug->getFunctionBlockType() ) - && ( functionBlockId == plug->getFunctionBlockId() ) - && ( plugAddressType == plug->getPlugAddressType() ) - && ( plugDirection == plug->getPlugDirection() ) - && ( plugId == plug->getPlugId() ) ) - { - return plug; - } - } - - return 0; -} - -AvPlug* -AvPlugManager::getPlug( int iGlobalId ) const -{ - for ( AvPlugVector::const_iterator it = m_plugs.begin(); - it != m_plugs.end(); - ++it ) - { - AvPlug* pPlug = *it; - if ( pPlug->getGlobalId() == iGlobalId ) { - return pPlug; - } - } - - return 0; -} - -AvPlugVector -AvPlugManager::getPlugsByType( AVCCommand::ESubunitType subunitType, - subunit_id_t subunitId, - function_block_type_t functionBlockType, - function_block_id_t functionBlockId, - AvPlug::EAvPlugAddressType plugAddressType, - AvPlug::EAvPlugDirection plugDirection, - AvPlug::EAvPlugType type) const -{ - debugOutput( DEBUG_LEVEL_VERBOSE, "SBT, SBID, FBT, FBID, AT, PD, T = " - "(0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x)\n", - subunitType, - subunitId, - functionBlockType, - functionBlockId, - plugAddressType, - plugDirection, - type ); - - AvPlugVector plugVector; - for ( AvPlugVector::const_iterator it = m_plugs.begin(); - it != m_plugs.end(); - ++it ) - { - AvPlug* pPlug = *it; - - if ( ( subunitType == pPlug->getSubunitType() ) - && ( subunitId == pPlug->getSubunitId() ) - && ( functionBlockType == pPlug->getFunctionBlockType() ) - && ( functionBlockId == pPlug->getFunctionBlockId() ) - && ( plugAddressType == pPlug->getPlugAddressType() ) - && ( plugDirection == pPlug->getPlugDirection() ) - && ( type == pPlug->getPlugType() ) ) - { - plugVector.push_back( pPlug ); - } - } - - return plugVector; -} - -bool -AvPlugManager::serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const -{ - bool result = true; - int i = 0; - for ( AvPlugVector::const_iterator it = m_plugs.begin(); - it != m_plugs.end(); - ++it ) - { - AvPlug* pPlug = *it; - std::ostringstream strstrm; - strstrm << basePath << i; - result &= pPlug->serialize( strstrm.str() + "/", ser ); - i++; - } - - return result; -} - -AvPlugManager* -AvPlugManager::deserialize( Glib::ustring basePath, - Util::IODeserialize& deser, - AvDevice& avDevice ) - -{ - AvPlugManager* pMgr = new AvPlugManager; - - if ( !pMgr ) { - return 0; - } - - int i = 0; - bool bFinished = false; - do { - std::ostringstream strstrm; - strstrm << basePath << i; - // avDevice still holds a null pointer for the plug manager - // therefore we have to *this as additional argument - AvPlug* pPlug = AvPlug::deserialize( strstrm.str() + "/", - deser, - avDevice, - *pMgr ); - if ( pPlug ) { - pMgr->m_plugs.push_back( pPlug ); - i++; - } else { - bFinished = true; - } - } while ( !bFinished ); - - return pMgr; -} - - -//////////////////////////////////// - -AvPlugConnection::AvPlugConnection( AvPlug& srcPlug, AvPlug& destPlug ) - : m_srcPlug( &srcPlug ) - , m_destPlug( &destPlug ) -{ -} - -AvPlugConnection::AvPlugConnection() - : m_srcPlug( 0 ) - , m_destPlug( 0 ) -{ -} - -bool -AvPlugConnection::serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const -{ - bool result; - result = ser.write( basePath + "m_srcPlug", m_srcPlug->getGlobalId() ); - result &= ser.write( basePath + "m_destPlug", m_destPlug->getGlobalId() ); - return result; -} - -AvPlugConnection* -AvPlugConnection::deserialize( Glib::ustring basePath, - Util::IODeserialize& deser, - AvDevice& avDevice ) -{ - if ( !deser.isExisting( basePath + "m_srcPlug" ) ) { - return 0; - } - - AvPlugConnection* pConnection = new AvPlugConnection; - if ( !pConnection ) { - return 0; - } - - bool result; - int iSrcPlugId; - int iDestPlugId; - result = deser.read( basePath + "m_srcPlug", iSrcPlugId ); - result &= deser.read( basePath + "m_destPlug", iDestPlugId ); - - if ( !result ) { - delete pConnection; - return 0; - } - - pConnection->m_srcPlug = avDevice.getPlugManager().getPlug( iSrcPlugId ); - pConnection->m_destPlug = avDevice.getPlugManager().getPlug( iDestPlugId ); - - if ( !pConnection->m_srcPlug || !pConnection->m_destPlug ) { - delete pConnection; - return 0; - } - - return pConnection; -} - -} +} Index: trunk/libffado/src/bebob/bebob_avdevice_subunit.cpp =================================================================== --- trunk/libffado/src/bebob/bebob_avdevice_subunit.cpp (revision 516) +++ trunk/libffado/src/bebob/bebob_avdevice_subunit.cpp (revision 554) @@ -28,257 +28,60 @@ #include "libieee1394/configrom.h" -#include "libavc/avc_plug_info.h" -#include "libavc/avc_extended_stream_format.h" -#include "libavc/avc_serialize.h" +#include "libavc/general/avc_plug_info.h" +#include "libavc/streamformat/avc_extended_stream_format.h" +#include "libavc/util/avc_serialize.h" #include -IMPL_DEBUG_MODULE( BeBoB::AvDeviceSubunit, BeBoB::AvDeviceSubunit, DEBUG_LEVEL_VERBOSE ); - -//////////////////////////////////////////// - -BeBoB::AvDeviceSubunit::AvDeviceSubunit( AvDevice& avDevice, - AVCCommand::ESubunitType type, - subunit_t id, - int verboseLevel ) - : m_avDevice( &avDevice ) - , m_sbType( type ) - , m_sbId( id ) - , m_verboseLevel( verboseLevel ) -{ - setDebugLevel( m_verboseLevel ); -} - -BeBoB::AvDeviceSubunit::AvDeviceSubunit() -{ -} - -BeBoB::AvDeviceSubunit::~AvDeviceSubunit() -{ - for ( AvPlugVector::iterator it = m_plugs.begin(); - it != m_plugs.end(); - ++it ) - { - delete *it; - } -} - -bool -BeBoB::AvDeviceSubunit::discover() -{ - if ( !discoverPlugs() ) { - debugError( "plug discovering failed\n" ); - return false; - } - - return true; -} - -bool -BeBoB::AvDeviceSubunit::discoverPlugs() -{ - PlugInfoCmd plugInfoCmd( m_avDevice->get1394Service(), - PlugInfoCmd::eSF_SerialBusIsochronousAndExternalPlug ); - plugInfoCmd.setNodeId( m_avDevice->getConfigRom().getNodeId() ); - plugInfoCmd.setCommandType( AVCCommand::eCT_Status ); - plugInfoCmd.setSubunitType( m_sbType ); - plugInfoCmd.setSubunitId( m_sbId ); - plugInfoCmd.setVerbose( m_verboseLevel ); - - if ( !plugInfoCmd.fire() ) { - debugError( "plug info command failed\n" ); - return false; - } - - debugOutput( DEBUG_LEVEL_NORMAL, "number of source plugs = %d\n", - plugInfoCmd.m_sourcePlugs ); - debugOutput( DEBUG_LEVEL_NORMAL, "number of destination output " - "plugs = %d\n", plugInfoCmd.m_destinationPlugs ); - - if ( !discoverPlugs( AvPlug::eAPD_Input, - plugInfoCmd.m_destinationPlugs ) ) - { - debugError( "destination plug discovering failed\n" ); - return false; - } - - if ( !discoverPlugs( AvPlug::eAPD_Output, - plugInfoCmd.m_sourcePlugs ) ) - { - debugError( "source plug discovering failed\n" ); - return false; - } - - return true; -} - -bool -BeBoB::AvDeviceSubunit::discoverConnections() -{ - for ( AvPlugVector::iterator it = m_plugs.begin(); - it != m_plugs.end(); - ++it ) - { - AvPlug* plug = *it; - if ( !plug->discoverConnections() ) { - debugError( "plug connection discovering failed ('%s')\n", - plug->getName() ); - return false; - } - } - - return true; -} - -bool -BeBoB::AvDeviceSubunit::discoverPlugs(AvPlug::EAvPlugDirection plugDirection, - plug_id_t plugMaxId ) -{ - for ( int plugIdx = 0; - plugIdx < plugMaxId; - ++plugIdx ) - { - AVCCommand::ESubunitType subunitType = - static_cast( getSubunitType() ); - AvPlug* plug = new AvPlug( m_avDevice->get1394Service(), - m_avDevice->getConfigRom(), - m_avDevice->getPlugManager(), - subunitType, - getSubunitId(), - 0xff, - 0xff, - AvPlug::eAPA_SubunitPlug, - plugDirection, - plugIdx, - m_verboseLevel ); - if ( !plug || !plug->discover() ) { - debugError( "plug discover failed\n" ); - return false; - } - - debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n", - plug->getName() ); - m_plugs.push_back( plug ); - } - return true; -} - -bool -BeBoB::AvDeviceSubunit::addPlug( AvPlug& plug ) -{ - m_plugs.push_back( &plug ); - return true; -} - - -BeBoB::AvPlug* -BeBoB::AvDeviceSubunit::getPlug(AvPlug::EAvPlugDirection direction, plug_id_t plugId) -{ - for ( AvPlugVector::iterator it = m_plugs.begin(); - it != m_plugs.end(); - ++it ) - { - AvPlug* plug = *it; - if ( ( plug->getPlugId() == plugId ) - && ( plug->getDirection() == direction ) ) - { - return plug; - } - } - return 0; -} - - -bool -BeBoB::AvDeviceSubunit::serialize( Glib::ustring basePath, - Util::IOSerialize& ser ) const -{ - bool result; - - result = ser.write( basePath + "m_sbType", m_sbType ); - result &= ser.write( basePath + "m_sbId", m_sbId ); - result &= ser.write( basePath + "m_verboseLevel", m_verboseLevel ); - result &= serializeChild( basePath, ser ); - - return result; -} - -BeBoB::AvDeviceSubunit* -BeBoB::AvDeviceSubunit::deserialize( Glib::ustring basePath, - Util::IODeserialize& deser, - AvDevice& avDevice ) -{ - bool result; - AVCCommand::ESubunitType sbType; - - if ( !deser.isExisting( basePath + "m_sbType" ) ) { - return 0; - } - - result = deser.read( basePath + "m_sbType", sbType ); - - AvDeviceSubunit* pSubunit = 0; - switch( sbType ) { - case AVCCommand::eST_Audio: - pSubunit = new AvDeviceSubunitAudio; - break; - case AVCCommand::eST_Music: - pSubunit = new AvDeviceSubunitMusic; - break; - default: - pSubunit = 0; - } - - if ( !pSubunit ) { - return 0; - } - - pSubunit->m_avDevice = &avDevice; - pSubunit->m_sbType = sbType; - result &= deser.read( basePath + "m_sbId", pSubunit->m_sbId ); - result &= deser.read( basePath + "m_verboseLevel", pSubunit->m_verboseLevel ); - result &= pSubunit->deserializeChild( basePath, deser, avDevice ); - - if ( !result ) { - delete pSubunit; - return 0; - } - - return pSubunit; -} - -//////////////////////////////////////////// - -BeBoB::AvDeviceSubunitAudio::AvDeviceSubunitAudio( AvDevice& avDevice, - subunit_t id, - int verboseLevel ) - : AvDeviceSubunit( avDevice, AVCCommand::eST_Audio, id, verboseLevel ) -{ -} - -BeBoB::AvDeviceSubunitAudio::AvDeviceSubunitAudio() - : AvDeviceSubunit() -{ -} - -BeBoB::AvDeviceSubunitAudio::~AvDeviceSubunitAudio() -{ - for ( FunctionBlockVector::iterator it = m_functions.begin(); - it != m_functions.end(); - ++it ) - { - delete *it; - } -} - -bool -BeBoB::AvDeviceSubunitAudio::discover() -{ - debugOutput(DEBUG_LEVEL_NORMAL, "Discovering Audio Subunit...\n"); - - if ( !AvDeviceSubunit::discover() ) { - return false; - } - +using namespace AVC; + +////////////////////////// + +BeBoB::SubunitAudio::SubunitAudio( AVC::Unit& avDevice, + subunit_t id ) + : AVC::SubunitAudio( avDevice, id ) +{ +} + +BeBoB::SubunitAudio::SubunitAudio() + : AVC::SubunitAudio() +{ +} + +BeBoB::SubunitAudio::~SubunitAudio() +{ + +} + +AVC::Plug * +BeBoB::SubunitAudio::createPlug( AVC::Unit* unit, + AVC::Subunit* subunit, + AVC::function_block_type_t functionBlockType, + AVC::function_block_type_t functionBlockId, + AVC::Plug::EPlugAddressType plugAddressType, + AVC::Plug::EPlugDirection plugDirection, + AVC::plug_id_t plugId ) +{ + + return new BeBoB::Plug( unit, + subunit, + functionBlockType, + functionBlockId, + plugAddressType, + plugDirection, + plugId ); +} + +bool +BeBoB::SubunitAudio::discover() +{ + debugOutput(DEBUG_LEVEL_NORMAL, "Discovering %s...\n", getName()); + + // discover the AV/C generic part + if ( !AVC::SubunitAudio::discover() ) { + return false; + } + + // do the remaining BeBoB audio subunit discovery if ( !discoverFunctionBlocks() ) { debugError( "function block discovering failed\n" ); @@ -290,8 +93,8 @@ bool -BeBoB::AvDeviceSubunitAudio::discoverConnections() +BeBoB::SubunitAudio::discoverConnections() { debugOutput(DEBUG_LEVEL_NORMAL, "Discovering connections...\n"); - if ( !AvDeviceSubunit::discoverConnections() ) { + if ( !Subunit::discoverConnections() ) { return false; } @@ -313,11 +116,11 @@ const char* -BeBoB::AvDeviceSubunitAudio::getName() -{ - return "AudioSubunit"; -} - -bool -BeBoB::AvDeviceSubunitAudio::discoverFunctionBlocks() +BeBoB::SubunitAudio::getName() +{ + return "BeBoB::AudioSubunit"; +} + +bool +BeBoB::SubunitAudio::discoverFunctionBlocks() { debugOutput( DEBUG_LEVEL_NORMAL, @@ -351,6 +154,6 @@ // print a function block list #ifdef DEBUG - if (getDebugLevel() >= DEBUG_LEVEL_NORMAL) { - + if ((int)getDebugLevel() >= DEBUG_LEVEL_NORMAL) { + for ( FunctionBlockVector::iterator it = m_functions.begin(); it != m_functions.end(); @@ -369,5 +172,5 @@ bool -BeBoB::AvDeviceSubunitAudio::discoverFunctionBlocksDo( +BeBoB::SubunitAudio::discoverFunctionBlocksDo( ExtendedSubunitInfoCmd::EFunctionBlockType fbType ) { @@ -378,10 +181,10 @@ do { ExtendedSubunitInfoCmd - extSubunitInfoCmd( m_avDevice->get1394Service() ); - extSubunitInfoCmd.setNodeId( m_avDevice->getConfigRom().getNodeId() ); + extSubunitInfoCmd( m_unit->get1394Service() ); + extSubunitInfoCmd.setNodeId( m_unit->getConfigRom().getNodeId() ); extSubunitInfoCmd.setCommandType( AVCCommand::eCT_Status ); extSubunitInfoCmd.setSubunitId( getSubunitId() ); extSubunitInfoCmd.setSubunitType( getSubunitType() ); - extSubunitInfoCmd.setVerbose( m_verboseLevel ); + extSubunitInfoCmd.setVerbose( (int)getDebugLevel() ); extSubunitInfoCmd.m_fbType = fbType; @@ -417,5 +220,5 @@ bool -BeBoB::AvDeviceSubunitAudio::createFunctionBlock( +BeBoB::SubunitAudio::createFunctionBlock( ExtendedSubunitInfoCmd::EFunctionBlockType fbType, ExtendedSubunitInfoPageData& data ) @@ -434,5 +237,5 @@ data.m_noOfInputPlugs, data.m_noOfOutputPlugs, - m_verboseLevel ); + (int)getDebugLevel() ); } break; @@ -444,5 +247,5 @@ data.m_noOfInputPlugs, data.m_noOfOutputPlugs, - m_verboseLevel ); + (int)getDebugLevel() ); } break; @@ -457,5 +260,5 @@ data.m_noOfInputPlugs, data.m_noOfOutputPlugs, - m_verboseLevel ); + (int)getDebugLevel() ); } break; @@ -474,5 +277,5 @@ data.m_noOfInputPlugs, data.m_noOfOutputPlugs, - m_verboseLevel ); + (int)getDebugLevel() ); debugWarning( "Dummy function block processing created. " "Implementation is missing\n" ); @@ -487,5 +290,5 @@ data.m_noOfInputPlugs, data.m_noOfOutputPlugs, - m_verboseLevel ); + (int)getDebugLevel() ); debugWarning( "Dummy function block codec created. " "Implementation is missing\n" ); @@ -513,5 +316,5 @@ BeBoB::FunctionBlock::ESpecialPurpose -BeBoB::AvDeviceSubunitAudio::convertSpecialPurpose( +BeBoB::SubunitAudio::convertSpecialPurpose( function_block_special_purpose_t specialPurpose ) { @@ -531,5 +334,5 @@ bool -BeBoB::AvDeviceSubunitAudio::serializeChild( Glib::ustring basePath, +BeBoB::SubunitAudio::serializeChild( Glib::ustring basePath, Util::IOSerialize& ser ) const { @@ -554,7 +357,7 @@ bool -BeBoB::AvDeviceSubunitAudio::deserializeChild( Glib::ustring basePath, +BeBoB::SubunitAudio::deserializeChild( Glib::ustring basePath, Util::IODeserialize& deser, - AvDevice& avDevice ) + AVC::Unit& avDevice ) { int i = 0; @@ -580,28 +383,62 @@ //////////////////////////////////////////// -BeBoB::AvDeviceSubunitMusic::AvDeviceSubunitMusic( AvDevice& avDevice, - subunit_t id, - int verboseLevel ) - : AvDeviceSubunit( avDevice, AVCCommand::eST_Music, id, verboseLevel ) -{ -} - -BeBoB::AvDeviceSubunitMusic::AvDeviceSubunitMusic() - : AvDeviceSubunit() -{ -} - -BeBoB::AvDeviceSubunitMusic::~AvDeviceSubunitMusic() -{ +BeBoB::SubunitMusic::SubunitMusic( AVC::Unit& avDevice, + subunit_t id ) + : AVC::SubunitMusic( avDevice, id ) +{ +} + +BeBoB::SubunitMusic::SubunitMusic() + : AVC::SubunitMusic() +{ +} + +BeBoB::SubunitMusic::~SubunitMusic() +{ +} + +AVC::Plug * +BeBoB::SubunitMusic::createPlug( AVC::Unit* unit, + AVC::Subunit* subunit, + AVC::function_block_type_t functionBlockType, + AVC::function_block_type_t functionBlockId, + AVC::Plug::EPlugAddressType plugAddressType, + AVC::Plug::EPlugDirection plugDirection, + AVC::plug_id_t plugId ) +{ + + return new BeBoB::Plug( unit, + subunit, + functionBlockType, + functionBlockId, + plugAddressType, + plugDirection, + plugId ); +} + +bool +BeBoB::SubunitMusic::discover() +{ + debugOutput(DEBUG_LEVEL_NORMAL, "Discovering %s...\n", getName()); + + // discover the AV/C generic part + if ( !AVC::SubunitMusic::discover() ) { + return false; + } + + // do the remaining BeBoB music subunit discovery + // which is nothing + + return true; } const char* -BeBoB::AvDeviceSubunitMusic::getName() -{ - return "MusicSubunit"; -} - -bool -BeBoB::AvDeviceSubunitMusic::serializeChild( Glib::ustring basePath, +BeBoB::SubunitMusic::getName() +{ + return "BeBoB::MusicSubunit"; +} + +bool +BeBoB::SubunitMusic::serializeChild( Glib::ustring basePath, Util::IOSerialize& ser ) const { @@ -610,8 +447,8 @@ bool -BeBoB::AvDeviceSubunitMusic::deserializeChild( Glib::ustring basePath, +BeBoB::SubunitMusic::deserializeChild( Glib::ustring basePath, Util::IODeserialize& deser, - AvDevice& avDevice ) -{ - return true; -} + AVC::Unit& avDevice ) +{ + return true; +} Index: trunk/libffado/src/bebob/bebob_functionblock.cpp =================================================================== --- trunk/libffado/src/bebob/bebob_functionblock.cpp (revision 516) +++ trunk/libffado/src/bebob/bebob_functionblock.cpp (revision 554) @@ -27,8 +27,12 @@ #include "libieee1394/configrom.h" -IMPL_DEBUG_MODULE( BeBoB::FunctionBlock, BeBoB::FunctionBlock, DEBUG_LEVEL_NORMAL ); - -BeBoB::FunctionBlock::FunctionBlock( - AvDeviceSubunit& subunit, +using namespace AVC; + +namespace BeBoB { + +IMPL_DEBUG_MODULE( FunctionBlock, FunctionBlock, DEBUG_LEVEL_NORMAL ); + +FunctionBlock::FunctionBlock( + AVC::Subunit& subunit, function_block_type_t type, function_block_type_t subtype, @@ -50,5 +54,5 @@ } -BeBoB::FunctionBlock::FunctionBlock( const FunctionBlock& rhs ) +FunctionBlock::FunctionBlock( const FunctionBlock& rhs ) : m_subunit( rhs.m_subunit ) , m_type( rhs.m_type ) @@ -62,11 +66,11 @@ } -BeBoB::FunctionBlock::FunctionBlock() -{ -} - -BeBoB::FunctionBlock::~FunctionBlock() -{ - for ( AvPlugVector::iterator it = m_plugs.begin(); +FunctionBlock::FunctionBlock() +{ +} + +FunctionBlock::~FunctionBlock() +{ + for ( PlugVector::iterator it = m_plugs.begin(); it != m_plugs.end(); ++it ) @@ -78,5 +82,5 @@ bool -BeBoB::FunctionBlock::discover() +FunctionBlock::discover() { debugOutput( DEBUG_LEVEL_NORMAL, @@ -87,5 +91,5 @@ m_nrOfOutputPlugs ); - if ( !discoverPlugs( AvPlug::eAPD_Input, m_nrOfInputPlugs ) ) { + if ( !discoverPlugs( AVC::Plug::eAPD_Input, m_nrOfInputPlugs ) ) { debugError( "Could not discover input plug for '%s'\n", getName() ); @@ -93,5 +97,5 @@ } - if ( !discoverPlugs( AvPlug::eAPD_Output, m_nrOfOutputPlugs ) ) { + if ( !discoverPlugs( AVC::Plug::eAPD_Output, m_nrOfOutputPlugs ) ) { debugError( "Could not discover output plugs for '%s'\n", getName() ); @@ -103,20 +107,16 @@ bool -BeBoB::FunctionBlock::discoverPlugs( AvPlug::EAvPlugDirection plugDirection, +FunctionBlock::discoverPlugs( AVC::Plug::EPlugDirection plugDirection, plug_id_t plugMaxId ) { for ( int plugId = 0; plugId < plugMaxId; ++plugId ) { - AvPlug* plug = new AvPlug( - m_subunit->getAvDevice().get1394Service(), - m_subunit->getAvDevice().getConfigRom(), - m_subunit->getAvDevice().getPlugManager(), - m_subunit->getSubunitType(), - m_subunit->getSubunitId(), + AVC::Plug* plug = new BeBoB::Plug( + &m_subunit->getUnit(), + m_subunit, m_type, m_id, - AvPlug::eAPA_FunctionBlockPlug, + AVC::Plug::eAPA_FunctionBlockPlug, plugDirection, - plugId, - m_verbose ); + plugId); if ( !plug || !plug->discover() ) { @@ -136,5 +136,5 @@ bool -BeBoB::FunctionBlock::discoverConnections() +FunctionBlock::discoverConnections() { debugOutput( DEBUG_LEVEL_VERBOSE, @@ -142,9 +142,13 @@ getName() ); - for ( AvPlugVector::iterator it = m_plugs.begin(); + for ( PlugVector::iterator it = m_plugs.begin(); it != m_plugs.end(); ++it ) { - AvPlug* plug = *it; + BeBoB::Plug* plug = dynamic_cast(*it); + if(!plug) { + debugError("BUG: not a bebob plug\n"); + return false; + } if ( !plug->discoverConnections() ) { debugError( "Could not discover plug connections\n" ); @@ -156,11 +160,11 @@ bool -serializeAvPlugVector( Glib::ustring basePath, +serializePlugVector( Glib::ustring basePath, Util::IOSerialize& ser, - const BeBoB::AvPlugVector& vec ) + const PlugVector& vec ) { bool result = true; int i = 0; - for ( BeBoB::AvPlugVector::const_iterator it = vec.begin(); + for ( PlugVector::const_iterator it = vec.begin(); it != vec.end(); ++it ) @@ -175,8 +179,8 @@ bool -deserializeAvPlugVector( Glib::ustring basePath, +deserializePlugVector( Glib::ustring basePath, Util::IODeserialize& deser, - BeBoB::AvDevice& avDevice, - BeBoB::AvPlugVector& vec ) + AVC::Unit& unit, + PlugVector& vec ) { int i = 0; @@ -190,5 +194,5 @@ if ( deser.isExisting( strstrm.str() ) ) { result &= deser.read( strstrm.str(), plugId ); - BeBoB::AvPlug* pPlug = avDevice.getPlugManager().getPlug( plugId ); + AVC::Plug* pPlug = unit.getPlugManager().getPlug( plugId ); if ( result && pPlug ) { @@ -207,5 +211,5 @@ bool -BeBoB::FunctionBlock::serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const +FunctionBlock::serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const { bool result; @@ -218,14 +222,14 @@ result &= ser.write( basePath + "m_nrOfOutputPlugs", m_nrOfOutputPlugs ); result &= ser.write( basePath + "m_verbose", m_verbose ); - result &= serializeAvPlugVector( basePath + "m_plugs", ser, m_plugs ); + result &= serializePlugVector( basePath + "m_plugs", ser, m_plugs ); return result; } -BeBoB::FunctionBlock* -BeBoB::FunctionBlock::deserialize( Glib::ustring basePath, +FunctionBlock* +FunctionBlock::deserialize( Glib::ustring basePath, Util::IODeserialize& deser, - AvDevice& avDevice, - AvDeviceSubunit& subunit ) + AVC::Unit& unit, + AVC::Subunit& subunit ) { bool result; @@ -274,5 +278,5 @@ result &= deser.read( basePath + "m_nrOfOutputPlugs", pFB->m_nrOfOutputPlugs ); result &= deser.read( basePath + "m_verbose", pFB->m_verbose ); - result &= deserializeAvPlugVector( basePath + "m_plugs", deser, avDevice, pFB->m_plugs ); + result &= deserializePlugVector( basePath + "m_plugs", deser, unit, pFB->m_plugs ); return 0; @@ -281,6 +285,6 @@ /////////////////////// -BeBoB::FunctionBlockSelector::FunctionBlockSelector( - AvDeviceSubunit& subunit, +FunctionBlockSelector::FunctionBlockSelector( + AVC::Subunit& subunit, function_block_id_t id, ESpecialPurpose purpose, @@ -299,5 +303,5 @@ } -BeBoB::FunctionBlockSelector::FunctionBlockSelector( +FunctionBlockSelector::FunctionBlockSelector( const FunctionBlockSelector& rhs ) : FunctionBlock( rhs ) @@ -305,15 +309,15 @@ } -BeBoB::FunctionBlockSelector::FunctionBlockSelector() +FunctionBlockSelector::FunctionBlockSelector() : FunctionBlock() { } -BeBoB::FunctionBlockSelector::~FunctionBlockSelector() +FunctionBlockSelector::~FunctionBlockSelector() { } const char* -BeBoB::FunctionBlockSelector::getName() +FunctionBlockSelector::getName() { return "Selector"; @@ -321,5 +325,5 @@ bool -BeBoB::FunctionBlockSelector::serializeChild( Glib::ustring basePath, +FunctionBlockSelector::serializeChild( Glib::ustring basePath, Util::IOSerialize& ser ) const { @@ -328,7 +332,7 @@ bool -BeBoB::FunctionBlockSelector::deserializeChild( Glib::ustring basePath, +FunctionBlockSelector::deserializeChild( Glib::ustring basePath, Util::IODeserialize& deser, - AvDevice& avDevice ) + AvDevice& unit ) { return true; @@ -337,6 +341,6 @@ /////////////////////// -BeBoB::FunctionBlockFeature::FunctionBlockFeature( - AvDeviceSubunit& subunit, +FunctionBlockFeature::FunctionBlockFeature( + AVC::Subunit& subunit, function_block_id_t id, ESpecialPurpose purpose, @@ -355,5 +359,5 @@ } -BeBoB::FunctionBlockFeature::FunctionBlockFeature( +FunctionBlockFeature::FunctionBlockFeature( const FunctionBlockFeature& rhs ) : FunctionBlock( rhs ) @@ -361,15 +365,15 @@ } -BeBoB::FunctionBlockFeature::FunctionBlockFeature() +FunctionBlockFeature::FunctionBlockFeature() : FunctionBlock() { } -BeBoB::FunctionBlockFeature::~FunctionBlockFeature() +FunctionBlockFeature::~FunctionBlockFeature() { } const char* -BeBoB::FunctionBlockFeature::getName() +FunctionBlockFeature::getName() { return "Feature"; @@ -377,5 +381,5 @@ bool -BeBoB::FunctionBlockFeature::serializeChild( Glib::ustring basePath, +FunctionBlockFeature::serializeChild( Glib::ustring basePath, Util::IOSerialize& ser ) const { @@ -384,7 +388,7 @@ bool -BeBoB::FunctionBlockFeature::deserializeChild( Glib::ustring basePath, +FunctionBlockFeature::deserializeChild( Glib::ustring basePath, Util::IODeserialize& deser, - AvDevice& avDevice ) + AvDevice& unit ) { return true; @@ -393,6 +397,6 @@ /////////////////////// -BeBoB::FunctionBlockEnhancedMixer::FunctionBlockEnhancedMixer( - AvDeviceSubunit& subunit, +FunctionBlockEnhancedMixer::FunctionBlockEnhancedMixer( + AVC::Subunit& subunit, function_block_id_t id, ESpecialPurpose purpose, @@ -411,5 +415,5 @@ } -BeBoB::FunctionBlockEnhancedMixer::FunctionBlockEnhancedMixer( +FunctionBlockEnhancedMixer::FunctionBlockEnhancedMixer( const FunctionBlockEnhancedMixer& rhs ) : FunctionBlock( rhs ) @@ -417,15 +421,15 @@ } -BeBoB::FunctionBlockEnhancedMixer::FunctionBlockEnhancedMixer() +FunctionBlockEnhancedMixer::FunctionBlockEnhancedMixer() : FunctionBlock() { } -BeBoB::FunctionBlockEnhancedMixer::~FunctionBlockEnhancedMixer() +FunctionBlockEnhancedMixer::~FunctionBlockEnhancedMixer() { } const char* -BeBoB::FunctionBlockEnhancedMixer::getName() +FunctionBlockEnhancedMixer::getName() { return "EnhancedMixer"; @@ -433,5 +437,5 @@ bool -BeBoB::FunctionBlockEnhancedMixer::serializeChild( Glib::ustring basePath, +FunctionBlockEnhancedMixer::serializeChild( Glib::ustring basePath, Util::IOSerialize& ser ) const { @@ -440,7 +444,7 @@ bool -BeBoB::FunctionBlockEnhancedMixer::deserializeChild( Glib::ustring basePath, +FunctionBlockEnhancedMixer::deserializeChild( Glib::ustring basePath, Util::IODeserialize& deser, - AvDevice& avDevice ) + AvDevice& unit ) { return true; @@ -449,6 +453,6 @@ /////////////////////// -BeBoB::FunctionBlockProcessing::FunctionBlockProcessing( - AvDeviceSubunit& subunit, +FunctionBlockProcessing::FunctionBlockProcessing( + AVC::Subunit& subunit, function_block_id_t id, ESpecialPurpose purpose, @@ -467,5 +471,5 @@ } -BeBoB::FunctionBlockProcessing::FunctionBlockProcessing( +FunctionBlockProcessing::FunctionBlockProcessing( const FunctionBlockProcessing& rhs ) : FunctionBlock( rhs ) @@ -473,15 +477,15 @@ } -BeBoB::FunctionBlockProcessing::FunctionBlockProcessing() +FunctionBlockProcessing::FunctionBlockProcessing() : FunctionBlock() { } -BeBoB::FunctionBlockProcessing::~FunctionBlockProcessing() +FunctionBlockProcessing::~FunctionBlockProcessing() { } const char* -BeBoB::FunctionBlockProcessing::getName() +FunctionBlockProcessing::getName() { return "Dummy Processing"; @@ -489,5 +493,5 @@ bool -BeBoB::FunctionBlockProcessing::serializeChild( Glib::ustring basePath, +FunctionBlockProcessing::serializeChild( Glib::ustring basePath, Util::IOSerialize& ser ) const { @@ -496,7 +500,7 @@ bool -BeBoB::FunctionBlockProcessing::deserializeChild( Glib::ustring basePath, +FunctionBlockProcessing::deserializeChild( Glib::ustring basePath, Util::IODeserialize& deser, - AvDevice& avDevice ) + AvDevice& unit ) { return true; @@ -505,6 +509,6 @@ /////////////////////// -BeBoB::FunctionBlockCodec::FunctionBlockCodec( - AvDeviceSubunit& subunit, +FunctionBlockCodec::FunctionBlockCodec( + AVC::Subunit& subunit, function_block_id_t id, ESpecialPurpose purpose, @@ -523,20 +527,20 @@ } -BeBoB::FunctionBlockCodec::FunctionBlockCodec( const FunctionBlockCodec& rhs ) +FunctionBlockCodec::FunctionBlockCodec( const FunctionBlockCodec& rhs ) : FunctionBlock( rhs ) { } -BeBoB::FunctionBlockCodec::FunctionBlockCodec() +FunctionBlockCodec::FunctionBlockCodec() : FunctionBlock() { } -BeBoB::FunctionBlockCodec::~FunctionBlockCodec() +FunctionBlockCodec::~FunctionBlockCodec() { } const char* -BeBoB::FunctionBlockCodec::getName() +FunctionBlockCodec::getName() { return "Dummy Codec"; @@ -544,5 +548,5 @@ bool -BeBoB::FunctionBlockCodec::serializeChild( Glib::ustring basePath, +FunctionBlockCodec::serializeChild( Glib::ustring basePath, Util::IOSerialize& ser ) const { @@ -551,8 +555,10 @@ bool -BeBoB::FunctionBlockCodec::deserializeChild( Glib::ustring basePath, +FunctionBlockCodec::deserializeChild( Glib::ustring basePath, Util::IODeserialize& deser, - AvDevice& avDevice ) -{ - return true; -} + AvDevice& unit ) +{ + return true; +} + +} Index: trunk/libffado/src/bebob/bebob_avplug.h =================================================================== --- trunk/libffado/src/bebob/bebob_avplug.h (revision 445) +++ trunk/libffado/src/bebob/bebob_avplug.h (revision 554) @@ -25,10 +25,11 @@ #define BEBOB_AVPLUG_H -#include "libavc/avc_signal_source.h" -#include "libavc/avc_extended_stream_format.h" -#include "libavc/avc_extended_plug_info.h" -#include "libavc/avc_extended_cmd_generic.h" +#include "libavc/ccm/avc_signal_source.h" +#include "libavc/streamformat/avc_extended_stream_format.h" +#include "libavc/general/avc_extended_plug_info.h" +#include "libavc/general/avc_extended_cmd_generic.h" #include "libavc/avc_definitions.h" -#include "libavc/avc_generic.h" +#include "libavc/general/avc_generic.h" +#include "libavc/general/avc_plug.h" #include "libutil/serialize.h" @@ -44,131 +45,26 @@ class AvDevice; -class AvPlugManager; -class AvPlug; -typedef std::vector AvPlugVector; - -class AvPlug { +class Plug : public AVC::Plug { public: - enum EAvPlugAddressType { - eAPA_PCR, - eAPA_ExternalPlug, - eAPA_AsynchronousPlug, - eAPA_SubunitPlug, - eAPA_FunctionBlockPlug, - eAPA_Undefined, - }; - - enum EAvPlugType { - eAPT_IsoStream, - eAPT_AsyncStream, - eAPT_Midi, - eAPT_Sync, - eAPT_Analog, - eAPT_Digital, - eAPT_Unknown, - }; - - enum EAvPlugDirection { - eAPD_Input, - eAPD_Output, - eAPD_Unknown, - }; - // \todo This constructors sucks. too many parameters. fix it. - AvPlug( Ieee1394Service& ieee1394Service, - ConfigRom& configRom, - AvPlugManager& plugManager, - AVCCommand::ESubunitType subunitType, - subunit_id_t subunitId, - function_block_type_t functionBlockType, - function_block_type_t functionBlockId, - EAvPlugAddressType plugAddressType, - EAvPlugDirection plugDirection, - plug_id_t plugId, - int verboseLevel ); - AvPlug( const AvPlug& rhs ); - virtual ~AvPlug(); + Plug( AVC::Unit* unit, + AVC::Subunit* subunit, + AVC::function_block_type_t functionBlockType, + AVC::function_block_type_t functionBlockId, + AVC::Plug::EPlugAddressType plugAddressType, + AVC::Plug::EPlugDirection plugDirection, + AVC::plug_id_t plugId ); + Plug( const Plug& rhs ); + virtual ~Plug(); bool discover(); bool discoverConnections(); - bool inquireConnnection( AvPlug& plug ); - bool setConnection( AvPlug& plug ); - - int getGlobalId() const - { return m_globalId; } - plug_id_t getPlugId() const - { return m_id; } - AVCCommand::ESubunitType getSubunitType() const - { return m_subunitType; } - subunit_id_t getSubunitId() const - { return m_subunitId; } - const char* getName() const - { return m_name.c_str(); } - EAvPlugDirection getPlugDirection() const - { return m_direction; } - sampling_frequency_t getSamplingFrequency() const - { return m_samplingFrequency; } - int getSampleRate() const; // 22050, 24000, 32000, ... - int getNrOfChannels() const; - int getNrOfStreams() const; - - EAvPlugDirection getDirection() const - { return m_direction; } - EAvPlugAddressType getPlugAddressType() const - { return m_addressType; } - EAvPlugType getPlugType() const - { return m_infoPlugType; } - - function_block_type_t getFunctionBlockType() const - { return m_functionBlockType; } - function_block_id_t getFunctionBlockId() const - { return m_functionBlockId; } - - const AvPlugVector& getInputConnections() const - { return m_inputConnections; } - const AvPlugVector& getOutputConnections() const - { return m_outputConnections; } - - static PlugAddress::EPlugDirection convertPlugDirection( - EAvPlugDirection direction); - - void showPlug() const; - - bool serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const; - static AvPlug* deserialize( Glib::ustring basePath, - Util::IODeserialize& deser, - AvDevice& avDevice, - AvPlugManager& plugManager ); - - bool deserializeUpdate( Glib::ustring basePath, - Util::IODeserialize& deser ); - public: - struct ChannelInfo { - stream_position_t m_streamPosition; - stream_position_location_t m_location; - Glib::ustring m_name; - }; - typedef std::vector ChannelInfoVector; - - struct ClusterInfo { - int m_index; - port_type_t m_portType; - Glib::ustring m_name; - - nr_of_channels_t m_nrOfChannels; - ChannelInfoVector m_channelInfos; - stream_format_t m_streamFormat; - }; - typedef std::vector ClusterInfoVector; - - ClusterInfoVector& getClusterInfos() - { return m_clusterInfos; } protected: - AvPlug(); + Plug(); bool discoverPlugType(); @@ -178,177 +74,14 @@ bool discoverChannelName(); bool discoverClusterInfo(); - bool discoverStreamFormat(); - bool discoverSupportedStreamFormats(); bool discoverConnectionsInput(); bool discoverConnectionsOutput(); - ExtendedPlugInfoCmd setPlugAddrToPlugInfoCmd(); - - ExtendedStreamFormatCmd setPlugAddrToStreamFormatCmd( - ExtendedStreamFormatCmd::ESubFunction subFunction); - - SignalSourceCmd setSrcPlugAddrToSignalCmd(); - - void setDestPlugAddrToSignalCmd( - SignalSourceCmd& signalSourceCmd, AvPlug& plug ); - - void debugOutputClusterInfos( int debugLevel ); - - bool copyClusterInfo(ExtendedPlugInfoPlugChannelPositionSpecificData& +private: + bool copyClusterInfo(AVC::ExtendedPlugInfoPlugChannelPositionSpecificData& channelPositionData ); - - bool addPlugConnection( AvPlugVector& connections, AvPlug& plug ); - - bool discoverConnectionsFromSpecificData( - EAvPlugDirection discoverDirection, - PlugAddressSpecificData* plugAddress, - AvPlugVector& connections ); - - AvPlug* getPlugDefinedBySpecificData( - UnitPlugSpecificDataPlugAddress* pUnitPlugAddress, - SubunitPlugSpecificDataPlugAddress* pSubunitPlugAddress, - FunctionBlockPlugSpecificDataPlugAddress* pFunctionBlockPlugAddress ); - - EAvPlugDirection toggleDirection( EAvPlugDirection direction ) const; - - const ClusterInfo* getClusterInfoByIndex( int index ) const; - - bool serializeChannelInfos( Glib::ustring basePath, - Util::IOSerialize& ser, - const ClusterInfo& clusterInfo ) const; - bool deserializeChannelInfos( Glib::ustring basePath, - Util::IODeserialize& deser, - ClusterInfo& clusterInfo ); - - bool serializeClusterInfos( Glib::ustring basePath, - Util::IOSerialize& ser ) const; - bool deserializeClusterInfos( Glib::ustring basePath, - Util::IODeserialize& deser ); - - bool serializeFormatInfos( Glib::ustring basePath, - Util::IOSerialize& ser ) const; - bool deserializeFormatInfos( Glib::ustring basePath, - Util::IODeserialize& deser ); - - bool serializeAvPlugVector( Glib::ustring basePath, - Util::IOSerialize& ser, - const AvPlugVector& vec) const; - bool deserializeAvPlugVector( Glib::ustring basePath, - Util::IODeserialize& deser, - AvPlugVector& vec ); - -private: - // Supported stream formats - struct FormatInfo { - FormatInfo() - : m_samplingFrequency( eSF_DontCare ) - , m_isSyncStream( false ) - , m_audioChannels( 0 ) - , m_midiChannels( 0 ) - , m_index( 0xff ) - {} - sampling_frequency_t m_samplingFrequency; - bool m_isSyncStream; - number_of_channels_t m_audioChannels; - number_of_channels_t m_midiChannels; - byte_t m_index; - }; - typedef std::vector FormatInfoVector; + AVC::ExtendedPlugInfoCmd setPlugAddrToPlugInfoCmd(); - Ieee1394Service* m_p1394Service; - ConfigRom* m_pConfigRom; - AVCCommand::ESubunitType m_subunitType; - subunit_id_t m_subunitId; - function_block_type_t m_functionBlockType; - function_block_id_t m_functionBlockId; - EAvPlugAddressType m_addressType; - EAvPlugDirection m_direction; - plug_id_t m_id; - EAvPlugType m_infoPlugType; - nr_of_channels_t m_nrOfChannels; - Glib::ustring m_name; - ClusterInfoVector m_clusterInfos; - sampling_frequency_t m_samplingFrequency; - FormatInfoVector m_formatInfos; - AvPlugVector m_inputConnections; - AvPlugVector m_outputConnections; - AvPlugManager* m_plugManager; - int m_verboseLevel; - int m_globalId; - static int m_globalIdCounter; - - DECLARE_DEBUG_MODULE; }; - -const char* avPlugAddressTypeToString( AvPlug::EAvPlugAddressType addressType ); -const char* avPlugTypeToString( AvPlug::EAvPlugType type ); -const char* avPlugDirectionToString( AvPlug::EAvPlugDirection direction ); - -class AvPlugManager -{ -public: - AvPlugManager( int verboseLevel ); - AvPlugManager( const AvPlugManager& rhs ); - ~AvPlugManager(); - - bool addPlug( AvPlug& plug ); - bool remPlug( AvPlug& plug ); - - void showPlugs() const; - - AvPlug* getPlug( AVCCommand::ESubunitType subunitType, - subunit_id_t subunitId, - function_block_type_t functionBlockType, - function_block_id_t functionBlockId, - AvPlug::EAvPlugAddressType plugAddressType, - AvPlug::EAvPlugDirection plugDirection, - plug_id_t plugId ) const; - AvPlug* getPlug( int iGlobalId ) const; - AvPlugVector getPlugsByType( AVCCommand::ESubunitType subunitType, - subunit_id_t subunitId, - function_block_type_t functionBlockType, - function_block_id_t functionBlockId, - AvPlug::EAvPlugAddressType plugAddressType, - AvPlug::EAvPlugDirection plugDirection, - AvPlug::EAvPlugType type) const; - - bool serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const; - static AvPlugManager* deserialize( Glib::ustring basePath, - Util::IODeserialize& deser, - AvDevice& avDevice ); - -private: - AvPlugManager(); - - int m_verboseLevel; - AvPlugVector m_plugs; - - DECLARE_DEBUG_MODULE; -}; - -class AvPlugConnection { -public: - AvPlugConnection( AvPlug& srcPlug, AvPlug& destPlug ); - - AvPlug& getSrcPlug() const - { return *m_srcPlug; } - AvPlug& getDestPlug() const - { return *m_destPlug; } - - bool serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const; - static AvPlugConnection* deserialize( Glib::ustring basePath, - Util::IODeserialize& deser, - AvDevice& avDevice ); -private: - AvPlugConnection(); - -private: - AvPlug* m_srcPlug; - AvPlug* m_destPlug; -}; - -typedef std::vector AvPlugConnectionVector; -typedef std::vector AvPlugConnectionOwnerVector; } Index: trunk/libffado/src/bebob/bebob_dl_mgr.cpp =================================================================== --- trunk/libffado/src/bebob/bebob_dl_mgr.cpp (revision 445) +++ trunk/libffado/src/bebob/bebob_dl_mgr.cpp (revision 554) @@ -29,9 +29,11 @@ #include "libieee1394/ieee1394service.h" -#include "libavc/avc_serialize.h" +#include "libavc/util/avc_serialize.h" #include #include + +using namespace AVC; namespace BeBoB { Index: trunk/libffado/src/bebob/bebob_avdevice_subunit.h =================================================================== --- trunk/libffado/src/bebob/bebob_avdevice_subunit.h (revision 451) +++ trunk/libffado/src/bebob/bebob_avdevice_subunit.h (revision 554) @@ -29,99 +29,50 @@ #include "debugmodule/debugmodule.h" -#include "libavc/avc_extended_subunit_info.h" +#include "libavc/general/avc_extended_subunit_info.h" #include "libavc/avc_definitions.h" -#include "libavc/avc_generic.h" +#include "libavc/general/avc_generic.h" #include +#include "libavc/general/avc_subunit.h" +#include "libavc/musicsubunit/avc_musicsubunit.h" +#include "libavc/audiosubunit/avc_audiosubunit.h" +#include "libavc/general/avc_plug.h" + namespace BeBoB { - -class AvDevice; - -class AvDeviceSubunit { - public: - AvDeviceSubunit( AvDevice& avDevice, - AVCCommand::ESubunitType type, - subunit_t id, - int verboseLevel ); - virtual ~AvDeviceSubunit(); - - virtual bool discover(); - virtual bool discoverConnections(); - virtual const char* getName() = 0; - - bool addPlug( AvPlug& plug ); - - subunit_t getSubunitId() - { return m_sbId; } - AVCCommand::ESubunitType getSubunitType() - { return m_sbType; } - - AvPlugVector& getPlugs() - { return m_plugs; } - AvPlug* getPlug(AvPlug::EAvPlugDirection direction, plug_id_t plugId); - - - AvDevice& getAvDevice() const - { return *m_avDevice; } - - - bool serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const; - static AvDeviceSubunit* deserialize( Glib::ustring basePath, - Util::IODeserialize& deser, - AvDevice& avDevice ); - protected: - AvDeviceSubunit(); - - bool discoverPlugs(); - bool discoverPlugs(AvPlug::EAvPlugDirection plugDirection, - plug_id_t plugMaxId ); - - virtual bool serializeChild( Glib::ustring basePath, - Util::IOSerialize& ser ) const = 0; - virtual bool deserializeChild( Glib::ustring basePath, - Util::IODeserialize& deser, - AvDevice& avDevice ) = 0; - - protected: - AvDevice* m_avDevice; - AVCCommand::ESubunitType m_sbType; - subunit_t m_sbId; - int m_verboseLevel; - - AvPlugVector m_plugs; - - DECLARE_DEBUG_MODULE; -}; - -typedef std::vector AvDeviceSubunitVector; ///////////////////////////// -class AvDeviceSubunitAudio: public AvDeviceSubunit { - public: - AvDeviceSubunitAudio( AvDevice& avDevice, - subunit_t id, - int verboseLevel ); - AvDeviceSubunitAudio(); - virtual ~AvDeviceSubunitAudio(); +class SubunitAudio : public AVC::SubunitAudio +{ +public: + SubunitAudio( AVC::Unit& avDevice, + AVC::subunit_t id ); + SubunitAudio(); + virtual ~SubunitAudio(); virtual bool discover(); virtual bool discoverConnections(); + virtual AVC::Plug *createPlug( AVC::Unit* unit, + AVC::Subunit* subunit, + AVC::function_block_type_t functionBlockType, + AVC::function_block_type_t functionBlockId, + AVC::Plug::EPlugAddressType plugAddressType, + AVC::Plug::EPlugDirection plugDirection, + AVC::plug_id_t plugId ); + virtual const char* getName(); - FunctionBlockVector getFunctionBlocks() { return m_functions; }; - protected: bool discoverFunctionBlocks(); bool discoverFunctionBlocksDo( - ExtendedSubunitInfoCmd::EFunctionBlockType fbType ); + AVC::ExtendedSubunitInfoCmd::EFunctionBlockType fbType ); bool createFunctionBlock( - ExtendedSubunitInfoCmd::EFunctionBlockType fbType, - ExtendedSubunitInfoPageData& data ); + AVC::ExtendedSubunitInfoCmd::EFunctionBlockType fbType, + AVC::ExtendedSubunitInfoPageData& data ); FunctionBlock::ESpecialPurpose convertSpecialPurpose( - function_block_special_purpose_t specialPurpose ); + AVC::function_block_special_purpose_t specialPurpose ); virtual bool serializeChild( Glib::ustring basePath, @@ -129,19 +80,27 @@ virtual bool deserializeChild( Glib::ustring basePath, Util::IODeserialize& deser, - AvDevice& avDevice ); + AVC::Unit& unit ); -protected: - FunctionBlockVector m_functions; }; ///////////////////////////// -class AvDeviceSubunitMusic: public AvDeviceSubunit { +class SubunitMusic : public AVC::SubunitMusic +{ public: - AvDeviceSubunitMusic( AvDevice& avDevice, - subunit_t id, - int verboseLevel ); - AvDeviceSubunitMusic(); - virtual ~AvDeviceSubunitMusic(); + SubunitMusic( AVC::Unit& avDevice, + AVC::subunit_t id ); + SubunitMusic(); + virtual ~SubunitMusic(); + + virtual bool discover(); + + virtual AVC::Plug *createPlug( AVC::Unit* unit, + AVC::Subunit* subunit, + AVC::function_block_type_t functionBlockType, + AVC::function_block_type_t functionBlockId, + AVC::Plug::EPlugAddressType plugAddressType, + AVC::Plug::EPlugDirection plugDirection, + AVC::plug_id_t plugId ); virtual const char* getName(); @@ -152,5 +111,6 @@ virtual bool deserializeChild( Glib::ustring basePath, Util::IODeserialize& deser, - AvDevice& avDevice ); + AVC::Unit& unit ); + }; Index: trunk/libffado/src/Makefile.am =================================================================== --- trunk/libffado/src/Makefile.am (revision 529) +++ trunk/libffado/src/Makefile.am (revision 554) @@ -49,5 +49,5 @@ libieee1394/IEC61883.h \ debugmodule/debugmodule.h \ - devicemanager.h fbtypes.h iavdevice.h threads.h bebob/bebob_avdevice.h \ + devicemanager.h fbtypes.h ffadodevice.h threads.h bebob/bebob_avdevice.h \ bebob/bebob_avdevice_subunit.h bebob/bebob_avplug.h bebob/bebob_dl_bcd.h bebob/bebob_dl_codes.h \ bebob/bebob_dl_mgr.h bebob/bebob_functionblock.h bounce/bounce_avdevice.h bounce/bounce_slave_avdevice.h bebob/bebob_configparser.h \ @@ -55,10 +55,27 @@ maudio/maudio_avdevice.h motu/motu_avdevice.h rme/rme_avdevice.h \ metrichalo/mh_avdevice.h dice/dice_avdevice.h \ - libavc/avc_connect.h \ - libavc/avc_definitions.h libavc/avc_extended_cmd_generic.h \ - libavc/avc_extended_plug_info.h libavc/avc_extended_stream_format.h \ - libavc/avc_extended_subunit_info.h libavc/avc_function_block.h libavc/avc_generic.h \ - libavc/avc_plug_info.h libavc/avc_serialize.h libavc/avc_signal_source.h \ - libavc/avc_subunit_info.h libavc/avc_unit_info.h \ + genericavc/avc_avdevice.h \ + libavc/streamformat/avc_extended_stream_format.h \ + libavc/util/avc_serialize.h \ + libavc/musicsubunit/avc_descriptor_music.h \ + libavc/musicsubunit/avc_musicsubunit.h \ + libavc/audiosubunit/avc_audiosubunit.h \ + libavc/audiosubunit/avc_function_block.h \ + libavc/descriptors/avc_descriptor_cmd.h \ + libavc/descriptors/avc_descriptor.h \ + libavc/general/avc_plug_info.h \ + libavc/general/avc_subunit_info.h \ + libavc/general/avc_extended_cmd_generic.h \ + libavc/general/avc_extended_subunit_info.h \ + libavc/general/avc_unit_info.h \ + libavc/general/avc_generic.h \ + libavc/general/avc_connect.h \ + libavc/general/avc_signal_format.h \ + libavc/general/avc_extended_plug_info.h \ + libavc/general/avc_unit.h \ + libavc/general/avc_subunit.h \ + libavc/general/avc_plug.h \ + libavc/avc_definitions.h \ + libavc/ccm/avc_signal_source.h \ libosc/OscArgument.h libosc/OscNode.h libosc/OscResponse.h libosc/OscServer.h libosc/OscMessage.h \ libosc/OscClient.h \ @@ -78,52 +95,61 @@ # common sources libffado_la_SOURCES = \ - devicemanager.cpp \ - ffado.cpp \ - ffado_streaming.cpp \ - iavdevice.cpp \ - debugmodule/debugmodule.cpp \ - libavc/avc_connect.cpp \ - libavc/avc_definitions.cpp \ - libavc/avc_extended_cmd_generic.cpp \ - libavc/avc_extended_plug_info.cpp \ - libavc/avc_extended_stream_format.cpp \ - libavc/avc_extended_subunit_info.cpp \ - libavc/avc_function_block.cpp \ - libavc/avc_generic.cpp \ - libavc/avc_plug_info.cpp \ - libavc/avc_serialize.cpp \ - libavc/avc_signal_source.cpp \ - libavc/avc_subunit_info.cpp \ - libavc/avc_unit_info.cpp \ - libieee1394/ARMHandler.cpp \ - libieee1394/configrom.cpp \ - libieee1394/csr1212.c \ - libieee1394/ieee1394service.cpp \ - libieee1394/IEC61883.cpp \ - libosc/OscArgument.cpp \ - libosc/OscClient.cpp \ - libosc/OscMessage.cpp \ - libosc/OscNode.cpp \ - libosc/OscResponse.cpp \ - libosc/OscServer.cpp \ - libstreaming/cip.c \ - libstreaming/IsoHandler.cpp \ - libstreaming/IsoHandlerManager.cpp \ - libstreaming/IsoStream.cpp \ - libstreaming/Port.cpp \ - libstreaming/PortManager.cpp \ - libstreaming/StreamProcessor.cpp \ - libstreaming/StreamProcessorManager.cpp \ - libutil/DelayLockedLoop.cpp \ - libutil/PacketBuffer.cpp \ - libutil/OptionContainer.cpp \ - libutil/PosixThread.cpp \ - libutil/ringbuffer.c \ - libutil/serialize.cpp \ - libutil/StreamStatistics.cpp \ - libutil/SystemTimeSource.cpp \ - libutil/Time.c \ - libutil/TimeSource.cpp \ - libutil/TimestampedBuffer.cpp + devicemanager.cpp \ + ffado.cpp \ + ffado_streaming.cpp \ + ffadodevice.cpp \ + debugmodule/debugmodule.cpp \ + libavc/streamformat/avc_extended_stream_format.cpp \ + libavc/util/avc_serialize.cpp \ + libavc/musicsubunit/avc_descriptor_music.cpp \ + libavc/musicsubunit/avc_musicsubunit.cpp \ + libavc/audiosubunit/avc_audiosubunit.cpp \ + libavc/audiosubunit/avc_function_block.cpp \ + libavc/descriptors/avc_descriptor_cmd.cpp \ + libavc/descriptors/avc_descriptor.cpp \ + libavc/general/avc_extended_subunit_info.cpp \ + libavc/general/avc_unit_info.cpp \ + libavc/general/avc_generic.cpp \ + libavc/general/avc_subunit_info.cpp \ + libavc/general/avc_connect.cpp \ + libavc/general/avc_signal_format.cpp \ + libavc/general/avc_extended_cmd_generic.cpp \ + libavc/general/avc_extended_plug_info.cpp \ + libavc/general/avc_plug_info.cpp \ + libavc/general/avc_unit.cpp \ + libavc/general/avc_subunit.cpp \ + libavc/general/avc_plug.cpp \ + libavc/avc_definitions.cpp \ + libavc/ccm/avc_signal_source.cpp \ + libieee1394/ARMHandler.cpp \ + libieee1394/configrom.cpp \ + libieee1394/csr1212.c \ + libieee1394/ieee1394service.cpp \ + libieee1394/IEC61883.cpp \ + libosc/OscArgument.cpp \ + libosc/OscClient.cpp \ + libosc/OscMessage.cpp \ + libosc/OscNode.cpp \ + libosc/OscResponse.cpp \ + libosc/OscServer.cpp \ + libstreaming/cip.c \ + libstreaming/IsoHandler.cpp \ + libstreaming/IsoHandlerManager.cpp \ + libstreaming/IsoStream.cpp \ + libstreaming/Port.cpp \ + libstreaming/PortManager.cpp \ + libstreaming/StreamProcessor.cpp \ + libstreaming/StreamProcessorManager.cpp \ + libutil/DelayLockedLoop.cpp \ + libutil/PacketBuffer.cpp \ + libutil/OptionContainer.cpp \ + libutil/PosixThread.cpp \ + libutil/ringbuffer.c \ + libutil/serialize.cpp \ + libutil/StreamStatistics.cpp \ + libutil/SystemTimeSource.cpp \ + libutil/Time.c \ + libutil/TimeSource.cpp \ + libutil/TimestampedBuffer.cpp # class specific sources @@ -140,4 +166,7 @@ maudio/maudio_avdevice.cpp +genericavc_src = \ + genericavc/avc_avdevice.cpp + motu_src = \ motu/motu_avdevice.cpp \ @@ -216,4 +245,11 @@ endif +if BUILD_GENERICAVC +libffado_la_SOURCES += $(genericavc_src) +bin_PROGRAMS += $(genericavc_bin) +noinst_PROGRAMS += $(genericavc_noinst) +nobase_dist_pkgdata_DATA += $(genericavc_pkgdata) +endif + if BUILD_BOUNCE libffado_la_SOURCES += $(bounce_src) Index: trunk/libffado/src/devicemanager.cpp =================================================================== --- trunk/libffado/src/devicemanager.cpp (revision 529) +++ trunk/libffado/src/devicemanager.cpp (revision 554) @@ -26,5 +26,5 @@ #include "devicemanager.h" -#include "iavdevice.h" +#include "ffadodevice.h" #include "libieee1394/configrom.h" @@ -38,4 +38,8 @@ #include "bebob/bebob_avdevice.h" #include "maudio/maudio_avdevice.h" +#endif + +#ifdef ENABLE_GENERICAVC + #include "genericavc/avc_avdevice.h" #endif @@ -72,5 +76,4 @@ , m_1394Service( 0 ) , m_oscServer( NULL ) - , m_verboseLevel( DEBUG_LEVEL_NORMAL ) { addOption(Util::OptionContainer::Option("slaveMode",false)); @@ -85,5 +88,5 @@ } - for ( IAvDeviceVectorIterator it = m_avDevices.begin(); + for ( FFADODeviceVectorIterator it = m_avDevices.begin(); it != m_avDevices.end(); ++it ) @@ -98,5 +101,5 @@ DeviceManager::setVerboseLevel(int l) { - m_verboseLevel=l; + debugOutput( DEBUG_LEVEL_NORMAL, "Setting verbose level to %d...\n", l ); setDebugLevel(l); @@ -105,5 +108,5 @@ OscNode::setVerboseLevel(l); - for ( IAvDeviceVectorIterator it = m_avDevices.begin(); + for ( FFADODeviceVectorIterator it = m_avDevices.begin(); it != m_avDevices.end(); ++it ) @@ -129,41 +132,41 @@ } - m_oscServer = new OSC::OscServer("17820"); - - if (!m_oscServer) { - debugFatal("failed to create osc server\n"); - delete m_1394Service; - m_1394Service = 0; - return false; - } - - if (!m_oscServer->init()) { - debugFatal("failed to init osc server\n"); - delete m_oscServer; - m_oscServer = NULL; - delete m_1394Service; - m_1394Service = 0; - return false; - } - - if (!m_oscServer->registerAtRootNode(this)) { - debugFatal("failed to register devicemanager at server\n"); - delete m_oscServer; - m_oscServer = NULL; - delete m_1394Service; - m_1394Service = 0; - return false; - } - - if (!m_oscServer->start()) { - debugFatal("failed to start osc server\n"); - delete m_oscServer; - m_oscServer = NULL; - delete m_1394Service; - m_1394Service = 0; - return false; - } - - setVerboseLevel(m_verboseLevel); +// m_oscServer = new OSC::OscServer("17820"); +// +// if (!m_oscServer) { +// debugFatal("failed to create osc server\n"); +// delete m_1394Service; +// m_1394Service = 0; +// return false; +// } +// +// if (!m_oscServer->init()) { +// debugFatal("failed to init osc server\n"); +// delete m_oscServer; +// m_oscServer = NULL; +// delete m_1394Service; +// m_1394Service = 0; +// return false; +// } +// +// if (!m_oscServer->registerAtRootNode(this)) { +// debugFatal("failed to register devicemanager at server\n"); +// delete m_oscServer; +// m_oscServer = NULL; +// delete m_1394Service; +// m_1394Service = 0; +// return false; +// } +// +// if (!m_oscServer->start()) { +// debugFatal("failed to start osc server\n"); +// delete m_oscServer; +// m_oscServer = NULL; +// delete m_1394Service; +// m_1394Service = 0; +// return false; +// } + + setVerboseLevel(getDebugLevel()); return true; } @@ -181,7 +184,7 @@ } - setVerboseLevel(m_verboseLevel); - - for ( IAvDeviceVectorIterator it = m_avDevices.begin(); + setVerboseLevel(getDebugLevel()); + + for ( FFADODeviceVectorIterator it = m_avDevices.begin(); it != m_avDevices.end(); ++it ) @@ -222,5 +225,7 @@ } - IAvDevice*avDevice = getDriverForDevice( configRom, nodeId ); + FFADODevice* avDevice = getDriverForDevice( configRom, + nodeId ); + if ( avDevice ) { debugOutput( DEBUG_LEVEL_NORMAL, @@ -234,5 +239,5 @@ } else if ( avDevice->discover() ) { debugOutput( DEBUG_LEVEL_VERBOSE, "discovering successful\n" ); - avDevice->setVerboseLevel( m_verboseLevel ); + avDevice->setVerboseLevel( getDebugLevel() ); } else { debugError( "could not discover device\n" ); @@ -256,5 +261,5 @@ } - if ( m_verboseLevel >= DEBUG_LEVEL_VERBOSE ) { + if ( getDebugLevel() >= DEBUG_LEVEL_VERBOSE ) { avDevice->showDevice(); } @@ -269,7 +274,12 @@ debugWarning("failed to register AvDevice at OSC server\n"); } + + debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d done...\n", nodeId ); } } + + debugOutput( DEBUG_LEVEL_NORMAL, "discovery finished...\n" ); + return true; @@ -294,5 +304,5 @@ } - IAvDevice* avDevice = getSlaveDriver( configRom ); + FFADODevice* avDevice = getSlaveDriver( configRom ); if ( avDevice ) { debugOutput( DEBUG_LEVEL_NORMAL, @@ -300,5 +310,5 @@ nodeId ); - avDevice->setVerboseLevel( m_verboseLevel ); + avDevice->setVerboseLevel( getDebugLevel() ); if ( !avDevice->discover() ) { @@ -311,11 +321,15 @@ debugError( "setting Id failed\n" ); } - if ( m_verboseLevel >= DEBUG_LEVEL_VERBOSE ) { + if ( getDebugLevel() >= DEBUG_LEVEL_VERBOSE ) { avDevice->showDevice(); } m_avDevices.push_back( avDevice ); + + debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d done...\n", nodeId ); } + debugOutput( DEBUG_LEVEL_NORMAL, "discovery finished...\n" ); + return true; } @@ -323,5 +337,5 @@ -IAvDevice* +FFADODevice* DeviceManager::getDriverForDevice( std::auto_ptr( configRom ), int id ) @@ -334,4 +348,11 @@ #endif +#ifdef ENABLE_GENERICAVC + debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Generic AV/C...\n" ); + if ( GenericAVC::AvDevice::probe( *configRom.get() ) ) { + return new GenericAVC::AvDevice( configRom, *m_1394Service, id ); + } +#endif + #ifdef ENABLE_BEBOB debugOutput( DEBUG_LEVEL_VERBOSE, "Trying M-Audio...\n" ); @@ -379,5 +400,5 @@ } -IAvDevice* +FFADODevice* DeviceManager::getSlaveDriver( std::auto_ptr( configRom ) ) { @@ -395,9 +416,9 @@ DeviceManager::isValidNode(int node) { - for ( IAvDeviceVectorIterator it = m_avDevices.begin(); + for ( FFADODeviceVectorIterator it = m_avDevices.begin(); it != m_avDevices.end(); ++it ) { - IAvDevice* avDevice = *it; + FFADODevice* avDevice = *it; if (avDevice->getConfigRom().getNodeId() == node) { @@ -422,5 +443,5 @@ } - IAvDevice* avDevice = m_avDevices.at( deviceNr ); + FFADODevice* avDevice = m_avDevices.at( deviceNr ); if ( !avDevice ) { @@ -431,12 +452,12 @@ } -IAvDevice* +FFADODevice* DeviceManager::getAvDevice( int nodeId ) { - for ( IAvDeviceVectorIterator it = m_avDevices.begin(); + for ( FFADODeviceVectorIterator it = m_avDevices.begin(); it != m_avDevices.end(); ++it ) { - IAvDevice* avDevice = *it; + FFADODevice* avDevice = *it; if ( avDevice->getConfigRom().getNodeId() == nodeId ) { return avDevice; @@ -447,5 +468,5 @@ } -IAvDevice* +FFADODevice* DeviceManager::getAvDeviceByIndex( int idx ) { @@ -469,5 +490,5 @@ Streaming::StreamProcessor * DeviceManager::getSyncSource() { - IAvDevice* device = getAvDeviceByIndex(0); + FFADODevice* device = getAvDeviceByIndex(0); bool slaveMode=false; Index: trunk/libffado/src/bounce/bounce_avdevice.cpp =================================================================== --- trunk/libffado/src/bounce/bounce_avdevice.cpp (revision 479) +++ trunk/libffado/src/bounce/bounce_avdevice.cpp (revision 554) @@ -28,9 +28,9 @@ #include "libieee1394/ieee1394service.h" -#include "libavc/avc_plug_info.h" -#include "libavc/avc_extended_plug_info.h" -#include "libavc/avc_subunit_info.h" -#include "libavc/avc_extended_stream_format.h" -#include "libavc/avc_serialize.h" +#include "libavc/general/avc_plug_info.h" +#include "libavc/general/avc_extended_plug_info.h" +#include "libavc/general/avc_subunit_info.h" +#include "libavc/streamformat/avc_extended_stream_format.h" +#include "libavc/util/avc_serialize.h" #include "libavc/avc_definitions.h" @@ -55,5 +55,5 @@ Ieee1394Service& ieee1394service, int nodeId ) - : IAvDevice( configRom, ieee1394service, nodeId ) + : FFADODevice( configRom, ieee1394service, nodeId ) , m_samplerate (44100) , m_model( NULL ) @@ -132,15 +132,15 @@ } +bool BounceDevice::setSamplingFrequency( int s ) { + if (s) { + m_samplerate=s; + return true; + } else return false; +} + int BounceDevice::getConfigurationId( ) { return 0; } -bool BounceDevice::setSamplingFrequency( ESamplingFrequency samplingFrequency ) { - int retval=convertESamplingFrequency( samplingFrequency ); - if (retval) { - m_samplerate=retval; - return true; - } else return false; -} bool Index: trunk/libffado/src/bounce/bounce_avdevice.h =================================================================== --- trunk/libffado/src/bounce/bounce_avdevice.h (revision 516) +++ trunk/libffado/src/bounce/bounce_avdevice.h (revision 554) @@ -28,5 +28,5 @@ #include "debugmodule/debugmodule.h" #include "libavc/avc_definitions.h" -#include "libavc/avc_extended_cmd_generic.h" +#include "libavc/general/avc_extended_cmd_generic.h" #include "libstreaming/AmdtpStreamProcessor.h" @@ -36,5 +36,5 @@ #include "libieee1394/ARMHandler.h" -#include "iavdevice.h" +#include "ffadodevice.h" #include @@ -65,5 +65,5 @@ }; -class BounceDevice : public IAvDevice { +class BounceDevice : public FFADODevice { private: class BounceNotifier; @@ -78,5 +78,5 @@ virtual bool discover(); - virtual bool setSamplingFrequency( ESamplingFrequency samplingFrequency ); + virtual bool setSamplingFrequency( int samplingFrequency ); virtual int getSamplingFrequency( ); Index: trunk/libffado/src/libosc/OscClient.cpp =================================================================== --- trunk/libffado/src/libosc/OscClient.cpp (revision 456) +++ trunk/libffado/src/libosc/OscClient.cpp (revision 554) @@ -73,4 +73,5 @@ debugOutput(DEBUG_LEVEL_VERBOSE, "Message on: %s\n", path); + return 0; } Index: trunk/libffado/src/maudio/maudio_avdevice.cpp =================================================================== --- trunk/libffado/src/maudio/maudio_avdevice.cpp (revision 479) +++ trunk/libffado/src/maudio/maudio_avdevice.cpp (revision 554) @@ -112,5 +112,5 @@ bool -AvDevice::setSamplingFrequency( ESamplingFrequency eSamplingFrequency ) +AvDevice::setSamplingFrequency( int eSamplingFrequency ) { // not supported Index: trunk/libffado/src/maudio/maudio_avdevice.h =================================================================== --- trunk/libffado/src/maudio/maudio_avdevice.h (revision 516) +++ trunk/libffado/src/maudio/maudio_avdevice.h (revision 554) @@ -28,5 +28,5 @@ #include "debugmodule/debugmodule.h" #include "libavc/avc_definitions.h" -#include "libavc/avc_extended_cmd_generic.h" +#include "libavc/general/avc_extended_cmd_generic.h" #include "bebob/bebob_avdevice.h" @@ -36,5 +36,5 @@ #include "libstreaming/AmdtpPortInfo.h" -#include "iavdevice.h" +#include "ffadodevice.h" class ConfigRom; @@ -64,5 +64,5 @@ virtual void showDevice(); - virtual bool setSamplingFrequency( ESamplingFrequency samplingFrequency ); + virtual bool setSamplingFrequency( int ); virtual int getSamplingFrequency( ); Index: trunk/libffado/src/iavdevice.cpp =================================================================== --- trunk/libffado/src/iavdevice.cpp (revision 529) +++ (revision ) @@ -1,107 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * Copyright (C) 2005-2007 by Pieter Palmers - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "iavdevice.h" - -#include "libieee1394/configrom.h" -#include "libieee1394/ieee1394service.h" - -#include -#include - -IMPL_DEBUG_MODULE( IAvDevice, IAvDevice, DEBUG_LEVEL_VERBOSE ); - -IAvDevice::IAvDevice( std::auto_ptr< ConfigRom >( configRom ), - Ieee1394Service& ieee1394service, - int nodeId ) - : OscNode() - , m_pConfigRom( configRom ) - , m_p1394Service( &ieee1394service ) - , m_verboseLevel( DEBUG_LEVEL_NORMAL ) - , m_nodeId ( nodeId ) -{ - addOption(Util::OptionContainer::Option("id",std::string("dev?"))); - - std::ostringstream nodestr; - nodestr << "node" << nodeId; - setOscBase(nodestr.str()); - ConfigRom& c = getConfigRom(); - - addChildOscNode(&c); -} - - -ConfigRom& -IAvDevice::getConfigRom() const -{ - return *m_pConfigRom; -} - -bool -IAvDevice::loadFromCache() -{ - return false; -} - -bool -IAvDevice::saveCache() -{ - return false; -} - -bool -IAvDevice::setId( unsigned int id) -{ - bool retval; - // FIXME: decent ID system nescessary - std::ostringstream idstr; - idstr << "dev" << id; - debugOutput( DEBUG_LEVEL_VERBOSE, "Set id to %s...\n", idstr.str().c_str()); - - - retval=setOption("id",idstr.str()); - if (retval) { - setOscBase(idstr.str()); - } - return retval; -} - -void -IAvDevice::setVerboseLevel(int l) -{ - m_verboseLevel=l; - setDebugLevel(l); -// m_pConfigRom->setVerboseLevel(l); - m_p1394Service->setVerboseLevel(l); -} - -bool -IAvDevice::enableStreaming() { - return true; -} - -bool -IAvDevice::disableStreaming() { - return true; -} Index: trunk/libffado/src/iavdevice.h =================================================================== --- trunk/libffado/src/iavdevice.h (revision 529) +++ (revision ) @@ -1,279 +1,0 @@ -/* - * Copyright (C) 2005-2007 by Daniel Wagner - * Copyright (C) 2005-2007 by Pieter Palmers - * - * This file is part of FFADO - * FFADO = Free Firewire (pro-)audio drivers for linux - * - * FFADO is based upon FreeBoB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#ifndef IAVDEVICE_H -#define IAVDEVICE_H - -#include "libavc/avc_definitions.h" -#include "libutil/OptionContainer.h" -#include "libosc/OscNode.h" - -class ConfigRom; -class Ieee1394Service; - -namespace Streaming { - class StreamProcessor; -} -/*! -@brief Base class for device support - - This class should be subclassed to implement ffado support - for a specific device. - -*/ -class IAvDevice - : public Util::OptionContainer, - public OSC::OscNode -{ -public: - IAvDevice( std::auto_ptr< ConfigRom >( configRom ), - Ieee1394Service& ieee1394service, - int nodeId ); - - virtual ~IAvDevice() {}; - - /// Returns the ConfigRom object of the device node. - ConfigRom& getConfigRom() const; - - /** - * @brief Called by DeviceManager to load device model from cache. - * - * This function is called before discover in order to speed up - * system initializing. - * - * @returns true if device was cached and successfully loaded from cache - */ - virtual bool loadFromCache(); - - /** - * @brief Called by DeviceManager to allow device driver to save a cache version - * of the current configuration. - * - * @returns true if caching was successful. False doesn't mean an error just, - * the driver was unable to store the configuration - */ - virtual bool saveCache(); - - /** - * @brief This is called by the DeviceManager to discover & configure the device - * - * @return true if the device was discovered successfuly - */ - virtual bool discover() = 0; - - /** - * @brief Set the samping frequency - * @param samplingFrequency - * @return true if successful - */ - virtual bool setSamplingFrequency( ESamplingFrequency samplingFrequency ) = 0; - /** - * @brief get the samplingfrequency as an integer - * @return the sampling frequency as integer - */ - virtual int getSamplingFrequency( ) = 0; - - /** - * @brief This is called by the device manager to give the device a unique ID. - * - * The purpose of this is to allow for unique port naming - * in case there are multiple identical devices on the bus. - * Some audio API's (e.g. jack) don't work properly when the - * port names are not unique. - * - * Say you have two devices having a port named OutputLeft. - * This can cause the streaming - * part to present two OutputLeft ports to the audio API, - * which won't work. This ID will allow you to construct - * the port names as 'dev1_OutputLeft' and 'dev2_OutputLeft' - * - * @note Currently this is a simple integer that is equal to - * the position of the device in the devicemanager's - * device list. Therefore it is dependant on the order - * in which the devices are detected. The side-effect - * of this is that it is dependant on the bus topology - * and history (e.g. busresets etc). This makes that - * these ID's are not fixed to a specific physical device. - * At some point, we will replaced this with a GUID based - * approach, which is tied to a physiscal device and is - * bus & time independant. - * - * @param id - * @return true if successful - */ - bool setId(unsigned int id); - - /** - * @brief Outputs the device configuration to stderr/stdout [debug helper] - * - * This function prints out a (detailed) description of the - * device detected, and its configuration. - */ - virtual void showDevice() = 0; - - /** - * @brief Lock the device - * - * This is called by the streaming layer before we start manipulating - * and/or using the device. - * - * It should implement the mechanisms provided by the device to - * make sure that no other controller claims control of the device. - * - * @return true if successful, false if not - */ - virtual bool lock() = 0; - - /** - * @brief Unlock the device - * - * This is called by the streaming layer after we finish manipulating - * and/or using the device. - * - * It should implement the mechanisms provided by the device to - * give up exclusive control of the device. - * - * @return true if successful, false if not - */ - virtual bool unlock() = 0; - - /** - * @brief Enable streaming on all 'started' streams - * - * Enables the ISO streaming on all streams that are 'started' - * using startStreamByIndex. This is useful to control a 'master enable' - * function on the device. - * - * @return true if successful - */ - virtual bool enableStreaming(); - - /** - * @brief Disable streaming on all streams - * - * Disables ISO streaming on all streams. - * This is useful to control a 'master enable' - * function on the device. - * - * @return true if successful - */ - virtual bool disableStreaming(); - - /** - * @brief Prepare the device - * - * This is called by the streaming layer after the configuration - * parameters (e.g. sample rate) are set, and before - * getStreamProcessor[*] functions are called. - * - * It should be used to prepare the device's streamprocessors - * based upon the device's current configuration. Normally - * the streaming layer will not change the device's configuration - * after calling this function. - * - * @return true if successful, false if not - */ - virtual bool prepare() = 0; - - /** - * @brief Returns the number of ISO streams implemented/used by this device - * - * Most likely this is 2 streams, i.e. one transmit stream and one - * receive stream. However there are devices that implement more, for - * example BeBoB's implement 4 streams: - * - 2 audio streams (1 xmit/1 recv) - * - 2 sync streams (1 xmit/1 recv), which are an optional sync source - * for the device. - * - * @note you have to have a StreamProcessor for every stream. I.e. - * getStreamProcessorByIndex(i) should return a valid StreamProcessor - * for i=0 to i=getStreamCount()-1 - * - * @return number of streams available (both transmit and receive) - */ - virtual int getStreamCount() = 0; - - /** - * @brief Returns the StreamProcessor object for the stream with index i - * - * @note a streamprocessor returned by getStreamProcessorByIndex(i) - * cannot be the same object as one returned by - * getStreamProcessorByIndex(j) if i isn't equal to j - * @note you cannot have two streamprocessors handling the same ISO - * channel (on the same port) - * - * @param i : Stream index - * @pre @ref i smaller than getStreamCount() - * @return a StreamProcessor object if successful, NULL otherwise - */ - virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i) = 0; - - /** - * @brief starts the stream with index i - * - * This function is called by the streaming layer when this stream should - * be started, i.e. the device should start sending data or should be prepared to - * be ready to receive data. - * - * It returns the channel number that was assigned for this stream. - * Channel allocation should be done using the allocation functions provided by the - * Ieee1394Service object that is passed in the constructor. - * - * @param i : Stream index - * @pre @ref i smaller than getStreamCount() - * @return true if successful, false if not - */ - virtual bool startStreamByIndex(int i) = 0; - - /** - * @brief stops the stream with index @ref i - * - * @param i : Stream index - * @pre @ref i smaller than getStreamCount() - * @return true if successful, false if not - */ - virtual bool stopStreamByIndex(int i) = 0; - - /** - * set verbosity level - */ - virtual void setVerboseLevel(int l); - - /** - * @brief return the node id of this device - * - * @return the node id - */ - int getNodeId() { return m_nodeId;}; - -protected: - std::auto_ptr( m_pConfigRom ); - Ieee1394Service* m_p1394Service; - int m_verboseLevel; - int m_nodeId; - - DECLARE_DEBUG_MODULE; -}; - -#endif