Changeset 1498

Show
Ignore:
Timestamp:
12/07/08 05:50:41 (12 years ago)
Author:
ppalmers
Message:

Merge all changes from 2.0 branch into trunk (since r1361). This _should_ contain all forward merges done in the mean time. At this moment in time both branches should be in sync.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/config.h.in

    r1348 r1498  
    4444#define IEEE1394SERVICE_CYCLETIMER_DLL_UPDATE_INTERVAL_USEC   200000 
    4545#define IEEE1394SERVICE_MAX_FIREWIRE_PORTS                         4 
     46#define IEEE1394SERVICE_MIN_SPLIT_TIMEOUT_USECS              1000000 
    4647 
    4748#define IEEE1394SERVICE_CYCLETIMER_HELPER_RUN_REALTIME       1 
    48 #define IEEE1394SERVICE_CYCLETIMER_HELPER_PRIO_INCREASE    -10 
     49#define IEEE1394SERVICE_CYCLETIMER_HELPER_PRIO               1 
    4950 
    5051// config rom read wait interval 
    5152#define IEEE1394SERVICE_CONFIGROM_READ_WAIT_USECS         1000 
    5253 
     54// FCP defines 
     55#define IEEE1394SERVICE_FCP_MAX_TRIES                       20 
     56#define IEEE1394SERVICE_FCP_SLEEP_BETWEEN_FAILURES_USECS  1000 
     57#define IEEE1394SERVICE_FCP_POLL_TIMEOUT_MSEC              200 
     58#define IEEE1394SERVICE_FCP_RESPONSE_TIMEOUT_USEC      2000000 
    5359 
    5460// The current version of libiec61883 doesn't seem to calculate 
     
    6268// due to weirdness in the kernel layer 
    6369#define MAX_XMIT_PACKET_SIZE                         (2048-16) 
    64 #define MAX_XMIT_NB_BUFFERS                                200 
    65  
    66 // should be PAGE_SIZE (4096) for unpatched kernels 
    67 #define RAW1394_RCV_MIN_BUF_STRIDE                        4096 
     70#define MIN_XMIT_PACKET_SIZE                                72 
     71#define MAX_XMIT_NB_BUFFERS                                128 
     72#define MAX_RECV_NB_BUFFERS                                 64 
     73#define MIN_RECV_PACKET_SIZE                               130 
     74 
     75// the default ISO receive mode.  
     76// 0 = auto, 1 = packet-per-buffer, 2 = bufferfill.  
     77// 'auto' will automatically choose the mode that is expected  
     78// to perform best for the given situation. For large periods  
     79// this is 'bufferfill' mode, for small periods this is  
     80// 'packet-per-buffer' mode. The 'BUFFERFILL_MODE_THRESHOLD'  
     81// defines what a 'large period' is. 
     82#define DEFAULT_ISO_RECEIVE_MODE                             0 
     83 
     84// the number of packets required to fill one period from which 
     85// the bufferfill mode is to be used 
     86#define BUFFERFILL_MODE_THRESHOLD                           64 
     87 
    6888 
    6989#define ISOHANDLER_FLUSH_BEFORE_ITERATE                      0 
     
    7191#define ISOHANDLER_DEATH_DETECT_TIMEOUT_USECS        1000000LL 
    7292 
    73 #define ISOHANDLER_CHECK_CTR_RECONSTRUCTION                  0 
     93#define ISOHANDLER_CHECK_CTR_RECONSTRUCTION                  1 
    7494 
    7595#define ISOHANDLERMANAGER_MAX_ISO_HANDLERS_PER_PORT         16 
     
    85105// prio 
    86106#define ISOHANDLERMANAGER_ISO_PRIO_INCREASE                  0 
    87 #define ISOHANDLERMANAGER_ISO_PRIO_INCREASE_RECV            -6 
     107#define ISOHANDLERMANAGER_ISO_PRIO_INCREASE_RECV            -1 
    88108#define ISOHANDLERMANAGER_ISO_PRIO_INCREASE_XMIT             1 
    89109 
     
    115135#define STREAMPROCESSORMANAGER_SYNCSTART_TRIES              10 
    116136#define STREAMPROCESSORMANAGER_SYNC_WAIT_TIME_MSEC          200 
     137#define STREAMPROCESSORMANAGER_NB_ALIGN_TRIES               40 
    117138#define STREAMPROCESSORMANAGER_ALIGN_AVERAGE_TIME_MSEC      400 
    118 #define STREAMPROCESSORMANAGER_NB_ALIGN_TRIES               40 
    119139 
    120140#define STREAMPROCESSORMANAGER_DYNAMIC_SYNC_DELAY           0 
  • trunk/libffado/configuration

    r1435 r1498  
    158158    driver      = 1; # BeBoB 
    159159}, 
     160 { 
     161   vendorid = 0x0000000A; 
     162   modelid = 0x00030000; 
     163   vendorname = "CME"; 
     164   modelname = "Matrix K FW"; 
     165   driver = 1; # BeBoB 
     166 },  
    160167 { 
    161168    vendorid = 0x1486; 
  • trunk/libffado/config_debug.h.in

    r1254 r1498  
    88#define DEBUG_USE_MESSAGE_BUFFER             1 
    99// max message length in the debug messagebuffer 
    10 #define DEBUG_MAX_MESSAGE_LENGTH          512 
     10#define DEBUG_MAX_MESSAGE_LENGTH          2048 
    1111// number of messages in the debug messagebuffer (power of two) 
    1212#define DEBUG_MB_BUFFERS                  1024 
     
    2222#define DEBUG_MESSAGE_BUFFER_COLLISION_WAIT_NTRIES      2 
    2323#define DEBUG_MESSAGE_BUFFER_COLLISION_WAIT_NSEC    50000 
    24  
    2524 
    2625// support a debug backlog 
  • trunk/libffado/external/libconfig/SConscript

    r1304 r1498  
    3737    env.AppendUnique( CCFLAGS=["-DDEBUG","-g"] ) 
    3838 
     39env.AppendUnique( CCFLAGS=["-DYY_NO_INPUT"] ) 
     40 
    3941libconfig = env.StaticLibrary('libconfigpp', sources) 
  • trunk/libffado/libffado/ffado.h

    r967 r1498  
    5555 
    5656/* various function */ 
    57  
    58 /* workaround: wait usec after each AVC command. 
    59    will disapear as soon bug is fixed */     
    60 void ffado_sleep_after_avc_command( int time ); 
    61  
    6257 
    6358/* The basic operation of the API is as follows: 
  • trunk/libffado/README

    r1336 r1498  
    9191match. The chances that it works also with an older versions are good: 
    9292 
    93 libxml++2   (>= 2.13.0
     93libxml++2   (>= 2.6.13
    9494 
    9595These libraries here should be at least the version listed: 
     
    9797libraw1394  (>= 1.3.0),  http://www.linux1394.org 
    9898libiec61883 (>= 1.1.0),  http://www.linux1394.org 
    99 libavc1394  (>= 0.5.3),  http://sourceforge.net/projects/libavc1394 
    10099dbus-1      (>= 1.0),    http://dbus.freedesktop.org 
    101100 
     
    111110To build the optional ffado device mixer control utility you also require: 
    112111 
    113 Qt          (>= 3.0),     http://trolltech.com/products/qt 
     112Qt          (>= 4.0),     http://trolltech.com/products/qt 
    114113SIP         (>= 4.7.0),   http://www.riverbankcomputing.co.uk/sip/index.php 
    115114PyQt        (note below), http://www.riverbankcomputing.co.uk/pyqt/ 
    116115dbus-python (>= 0.82.0),  http://dbus.freedesktop.org/releases/dbus-python/ 
    117116 
    118 The version of PyQt must be chosen to match the version of Qt in use.  For 
    119 Qt 4.x use PyQt 4.x, while PyQt 3.x is applicable for all other Qt versions 
    120 from 1.43. 
     117The mixer applets are available for both QT3 and QT4. However, the QT3 versions 
     118are no longer actively developed. The build script will automatically fallback 
     119to the QT3 version if you don't have QT4 installed. 
     120 
     121The version of PyQt must be chosen to exactly match the version of Qt in use. 
     122For Qt 4.x use PyQt 4.x. 
    121123 
    122124SIP is only required to compile PyQt.  If using a binary package of PyQt 
  • trunk/libffado/SConstruct

    r1493 r1498  
    2525 
    2626FFADO_API_VERSION="8" 
    27 FFADO_VERSION="2.0.900" 
     27FFADO_VERSION="2.999.0" 
    2828 
    2929import os 
     
    6363        BoolOption( "ENABLE_FIREWORKS", "Enable/Disable the ECHO Audio FireWorks AV/C part.", True ), 
    6464        BoolOption( "ENABLE_MOTU", "Enable/Disable the MOTU part.", True ), 
    65         BoolOption( "ENABLE_DICE", "Enable/Disable the DICE part.", False ), 
     65        BoolOption( "ENABLE_DICE", "Enable/Disable the DICE part.", True ), 
    6666        BoolOption( "ENABLE_METRIC_HALO", "Enable/Disable the Metric Halo part.", False ), 
    6767        BoolOption( "ENABLE_RME", "Enable/Disable the RME part.", False ), 
     
    9494        'XDG_DATA_DIRS', 
    9595        'HOME', 
     96        'CC', 
     97        'CFLAGS', 
     98        'CXX', 
     99        'CXXFLAGS', 
     100        'CPPFLAGS', 
    96101] 
    97102for var in vars_to_check: 
     
    103108env = Environment( tools=['default','scanreplace','pyuic','pyuic4','dbus','doxygen','pkgconfig'], toolpath=['admin'], ENV = buildenv, options=opts ) 
    104109 
    105 if os.environ.has_key('CC'): 
    106         env['CC'] = os.environ['CC'] 
    107 if os.environ.has_key('CXX'): 
    108         env['CXX'] = os.environ['CXX'] 
     110if os.environ.has_key('LDFLAGS'): 
     111        env['LINKFLAGS'] = os.environ['LDFLAGS'] 
    109112 
    110113# grab OS CFLAGS / CCFLAGS 
     
    223226        pkgs = { 
    224227                'libraw1394' : '1.3.0', 
    225                 'libavc1394' : '0.5.3', 
    226228                'libiec61883' : '1.1.0', 
    227229                'dbus-1' : '1.0', 
     
    529531 
    530532env['USER_CONFIG_FILE'] = env['CONFIGDIR'] + "/configuration" 
    531 env['SYSTEM_CONFIG_FILE'] = env['sharedir'] + "/configuration" 
     533env['SYSTEM_CONFIG_FILE'] = env['SHAREDIR'] + "/configuration" 
    532534 
    533535env['REGISTRATION_URL'] = "http://ffado.org/deviceregistration/register.php?action=register" 
     
    542544# 
    543545env.ScanReplace( "config.h.in" ) 
     546env.ScanReplace( "config_debug.h.in" ) 
     547env.ScanReplace( "version.h.in" ) 
     548 
    544549# ensure that the config.h is updated 
    545550env.Depends( "config.h", "SConstruct" ) 
    546551env.Depends( "config.h", 'cache/' + build_base + "options.cache" ) 
    547552 
    548 env.ScanReplace( "config_debug.h.in" ) 
    549  
    550 env.ScanReplace( "version.h.in" ) 
    551 env.Depends( "version.h", "SConstruct" ) 
    552 env.Depends( "version.h", 'cache/' + build_base + "options.cache" ) 
    553 # update version.h whenever the SVN revision changes 
     553# update version.h whenever the version or SVN revision changes 
    554554env.Depends( "version.h", env.Value(env['REVISION'])) 
     555env.Depends( "version.h", env.Value(env['VERSION'])) 
    555556 
    556557env.Depends( "libffado.pc", "SConstruct" ) 
     
    575576    if env['BUILD_TESTS']: 
    576577        Default( 'tests' ) 
    577  
    578 if not env.has_key( 'DESTDIR' ): 
    579         env.Execute( env.Action( "rm -f %s/ffadomixer" % env['bindir'] ) ) 
    580578 
    581579# 
     
    601599                        env.Execute( action ) 
    602600 
    603         if env.has_key( 'XDG_TOOLS' ) and env.has_key( 'PYUIC' ): 
     601        if env.has_key( 'XDG_TOOLS' ) and env.has_key( 'PYUIC4' ): 
    604602                if not env.GetOption("clean"): 
    605603                        action = "install" 
  • trunk/libffado/src/bebob/bebob_avdevice.cpp

    r1361 r1498  
    6262AvDevice::AvDevice( DeviceManager& d, std::auto_ptr< ConfigRom >( configRom ) ) 
    6363    : GenericAVC::AvDevice( d, configRom ) 
     64    , m_last_discovery_config_id ( 0xFFFFFFFFFFFFFFFFLLU ) 
    6465    , m_Mixer ( 0 ) 
    6566{ 
    6667    debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::AvDevice (NodeID %d)\n", 
    6768                 getConfigRom().getNodeId() ); 
    68  
    69     // DM1500 based devices seem to upset the linux1394 stack when commands are 
    70     // sent too fast. 
    71     if (AVC::AVCCommand::getSleepAfterAVCCommand() < 200) { 
    72         AVC::AVCCommand::setSleepAfterAVCCommand( 200 ); 
    73     } 
    74  
    7569} 
    7670 
     
    8478{ 
    8579    if(generic) { 
    86         return false; 
    8780        // try a bebob-specific command to check for the firmware 
    8881        ExtendedPlugInfoCmd extPlugInfoCmd( configRom.get1394Service() ); 
     
    9992        extendedPlugInfoInfoType.initialize(); 
    10093        extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType ); 
    101      
     94 
    10295        if ( !extPlugInfoCmd.fire() ) { 
    10396            debugError( "Number of channels command failed\n" ); 
    10497            return false; 
    10598        } 
    106      
     99 
     100        if((extPlugInfoCmd.getResponse() != AVCCommand::eR_Implemented)) { 
     101            // command not supported 
     102            return false; 
     103        } 
     104 
    107105        ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType(); 
    108106        if ( infoType 
     
    208206        debugWarning("Could not build mixer\n"); 
    209207    } 
     208 
     209    // keep track of the config id of this discovery 
     210    m_last_discovery_config_id = getConfigurationId(); 
     211 
    210212    return true; 
    211213} 
     
    656658} 
    657659 
     660bool 
     661AvDevice::needsRediscovery() 
     662{ 
     663    // require rediscovery if the config id differs from the one saved 
     664    // in the previous discovery 
     665    return getConfigurationId() != m_last_discovery_config_id; 
     666} 
     667 
    658668uint64_t 
    659669AvDevice::getConfigurationId() 
  • trunk/libffado/src/bebob/bebob_avdevice.h

    r1361 r1498  
    112112 
    113113    virtual uint64_t getConfigurationId(); 
     114    virtual bool needsRediscovery(); 
    114115 
    115116    std::string getCachePath(); 
     
    121122 
    122123    std::vector<int> m_supported_frequencies; 
     124    uint64_t         m_last_discovery_config_id; 
     125 
    123126protected: 
    124127    Mixer*             m_Mixer; 
  • trunk/libffado/src/bebob/bebob_mixer.cpp

    r1361 r1498  
    7979      ++it ) 
    8080    { 
    81         debugOutput(DEBUG_LEVEL_NORMAL,"deleting %s...\n", (*it)->getName().c_str()); 
     81        debugOutput(DEBUG_LEVEL_VERBOSE,"deleting %s...\n", (*it)->getName().c_str()); 
    8282        delete *it; 
    8383    } 
     
    124124bool 
    125125Mixer::addElementForAllFunctionBlocks() { 
    126     debugOutput(DEBUG_LEVEL_NORMAL,"Adding elements for functionblocks...\n"); 
     126    debugOutput(DEBUG_LEVEL_VERBOSE,"Adding elements for functionblocks...\n"); 
    127127 
    128128    bool retval = true; 
  • trunk/libffado/src/bebob/edirol/edirol_fa101.cpp

    r1199 r1498  
    4141    m_fixed_clocksource.description = "Device Controlled"; 
    4242 
    43     if (AVC::AVCCommand::getSleepAfterAVCCommand() < 500) { 
    44         AVC::AVCCommand::setSleepAfterAVCCommand( 500 ); 
    45     } 
     43    get1394Service().setFCPResponseFiltering(true); 
    4644} 
    4745 
  • trunk/libffado/src/bebob/focusrite/focusrite_cmd.h

    r864 r1498  
    2929#include "libavc/general/avc_vendor_dependent_cmd.h" 
    3030 
    31 #include <libavc1394/avc1394.h> 
    32  
    3331namespace BeBoB { 
    3432namespace Focusrite { 
  • trunk/libffado/src/bebob/focusrite/focusrite_generic.cpp

    r1336 r1498  
    449449 
    450450// hardware dial control 
    451 DialPositionControl::DialPositionControl(FocusriteDevice& parent, int id) 
    452 : Control::Discrete(&parent) 
    453 , m_Parent(parent) 
    454 , m_cmd_id ( id ) 
     451DialPositionControl::DialPositionControl(FocusriteDevice& parent, int id, int shift) 
     452: Control::Discrete(&parent) 
     453, m_Parent(parent) 
     454, m_cmd_id ( id ) 
     455, m_shift ( shift ) 
    455456{} 
    456 DialPositionControl::DialPositionControl(FocusriteDevice& parent, int id, 
     457DialPositionControl::DialPositionControl(FocusriteDevice& parent, int id, int shift, 
    457458                std::string name, std::string label, std::string descr) 
    458459: Control::Discrete(&parent) 
    459460, m_Parent(parent) 
    460461, m_cmd_id ( id ) 
     462, m_shift ( shift ) 
    461463{ 
    462464    setName(name); 
     
    474476        return 0; 
    475477    } else { 
    476         val = val >> 5; 
     478        if (m_shift > 0) { 
     479            val = val >> m_shift; 
     480        } else if (m_shift < 0) { 
     481            val = val << -m_shift; 
     482        } 
    477483        debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for %d = %d\n",  
    478484                                         m_cmd_id, val); 
  • trunk/libffado/src/bebob/focusrite/focusrite_generic.h

    r1336 r1498  
    150150{ 
    151151public: 
    152     DialPositionControl(FocusriteDevice& parent, int id); 
    153     DialPositionControl(FocusriteDevice& parent, int id, 
     152    DialPositionControl(FocusriteDevice& parent, int id, int shift); 
     153    DialPositionControl(FocusriteDevice& parent, int id, int shift, 
    154154                        std::string name, std::string label, std::string descr); 
    155155     
     
    166166    FocusriteDevice&        m_Parent; 
    167167    unsigned int            m_cmd_id; 
     168    int                     m_shift; 
    168169}; 
    169170 
  • trunk/libffado/src/bebob/focusrite/focusrite_saffire.cpp

    r1336 r1498  
    3535                 getConfigRom().getNodeId() ); 
    3636 
    37     // the saffire doesn't seem to like it if the commands are too fast 
    38     if (AVC::AVCCommand::getSleepAfterAVCCommand() < 1000) { 
    39         AVC::AVCCommand::setSleepAfterAVCCommand( 1000 ); 
    40     } 
    41  
    4237    if(getConfigRom().getGuid() < 0x130e0100040000LL) { 
    4338        m_isSaffireLE = false; 
     
    253248        result &= m_MixerContainer->addElement( 
    254249            new DialPositionControl(*this,  
    255                     FR_SAFFIRE_CMD_ID_MONITOR_DIAL, 
     250                    FR_SAFFIRE_CMD_ID_MONITOR_DIAL, 0, 
    256251                    "MonitorDial", "Monitor Dial", "Monitor Dial Value")); 
    257252 
     
    384379    delete m_MixerContainer; 
    385380    return true; 
     381} 
     382 
     383std::vector<int> 
     384SaffireDevice::getSupportedSamplingFrequencies() 
     385{ 
     386    std::vector<int> frequencies; 
     387    frequencies.push_back(44100); 
     388    frequencies.push_back(48000); 
     389    frequencies.push_back(88200); 
     390    frequencies.push_back(96000); 
     391    return frequencies; 
    386392} 
    387393 
  • trunk/libffado/src/bebob/focusrite/focusrite_saffire.h

    r1336 r1498  
    278278    virtual bool buildMixer(); 
    279279    virtual bool destroyMixer(); 
     280    virtual std::vector<int> getSupportedSamplingFrequencies(); 
    280281 
    281282private: 
  • trunk/libffado/src/bebob/focusrite/focusrite_saffirepro.cpp

    r1336 r1498  
    4444 
    4545    addOption(Util::OptionContainer::Option("rebootOnSamplerateChange", true)); 
    46     // the saffire pro doesn't seem to like it if the commands are too fast 
    47     if (AVC::AVCCommand::getSleepAfterAVCCommand() < 500) { 
    48         AVC::AVCCommand::setSleepAfterAVCCommand( 500 ); 
    49     } 
    5046 
    5147    updateClockSources(); 
     
    6258    bool result=true; 
    6359    debugOutput(DEBUG_LEVEL_VERBOSE, "Building a Focusrite SaffirePro mixer...\n"); 
    64      
     60 
    6561    destroyMixer(); 
    66      
     62 
    6763    // create the mixer object container 
    6864    m_MixerContainer = new Control::Container(this, "Mixer"); 
     
    144140                FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT78, FR_SAFFIREPRO_CMD_BITFIELD_BIT_DIM, 
    145141                "Out78Dim", "Out7/8 Dim", "Output 7/8 Level Dim")); 
     142 
     143    // front panel dial position 
     144    result &= m_MixerContainer->addElement( 
     145        new DialPositionControl(*this,  
     146                FR_SAFFIREPRO_CMD_ID_MONITOR_DIAL, 0, 
     147                "MonitorDial", "Monitor Dial", "Monitor Dial Value")); 
    146148 
    147149    // direct monitoring controls 
     
    309311            "DeviceName", "Flash Device Name", "Device name stored in flash memory"); 
    310312    result &= m_ControlContainer->addElement(m_deviceNameControl); 
     313 
     314    // add a direct register access element 
     315    result &= addElement(new RegisterControl(*this, "Register", "Register Access", "Direct register access")); 
    311316 
    312317    if (!result) { 
     
    420425    debugOutput(DEBUG_LEVEL_VERBOSE, "SYNC_CONFIG field value: %08lX\n", sync ); 
    421426 
    422     switch(sync & 0xFF) { 
     427    switch(sync & FR_SAFFIREPRO_CMD_ID_SYNC_CONFIG_MASK) { 
    423428        default: 
    424429            debugWarning( "Unexpected SYNC_CONFIG field value: %08lX\n", sync ); 
     
    432437            break; 
    433438        case FR_SAFFIREPRO_CMD_SYNC_CONFIG_ADAT1: 
     439            m_adat1_clocksource.active=true; 
     440            m_active_clocksource = &m_adat1_clocksource; 
     441            break; 
     442        case FR_SAFFIREPRO_CMD_SYNC_CONFIG_ADAT2: 
     443            m_adat2_clocksource.active=true; 
     444            m_active_clocksource = &m_adat2_clocksource; 
     445            break; 
     446        case FR_SAFFIREPRO_CMD_SYNC_CONFIG_WORDCLOCK: 
    434447            m_wordclock_clocksource.active=true; 
    435448            m_active_clocksource = &m_wordclock_clocksource; 
    436449            break; 
    437         case FR_SAFFIREPRO_CMD_SYNC_CONFIG_ADAT2: 
    438             m_adat1_clocksource.active=true; 
    439             m_active_clocksource = &m_adat1_clocksource; 
    440             break; 
    441         case FR_SAFFIREPRO_CMD_SYNC_CONFIG_WORDCLOCK: 
    442             m_adat2_clocksource.active=true; 
    443             m_active_clocksource = &m_adat2_clocksource; 
    444             break; 
    445     } 
    446     switch((sync >> 8) & 0xFF) { 
     450    } 
     451    switch((sync && FR_SAFFIREPRO_CMD_ID_SYNC_LOCK_MASK) >> 8) { 
    447452        case FR_SAFFIREPRO_CMD_SYNC_CONFIG_INTERNAL: 
    448453            // always locked 
     
    452457            break; 
    453458        case FR_SAFFIREPRO_CMD_SYNC_CONFIG_ADAT1: 
    454             m_wordclock_clocksource.locked=true; 
     459            m_adat1_clocksource.locked=true; 
    455460            break; 
    456461        case FR_SAFFIREPRO_CMD_SYNC_CONFIG_ADAT2: 
    457             m_adat1_clocksource.locked=true; 
     462            m_adat2_clocksource.locked=true; 
    458463            break; 
    459464        case FR_SAFFIREPRO_CMD_SYNC_CONFIG_WORDCLOCK: 
    460             m_adat2_clocksource.locked=true; 
     465            m_wordclock_clocksource.locked=true; 
    461466            break; 
    462467        default: 
     
    513518} 
    514519 
     520std::vector<int> 
     521SaffireProDevice::getSupportedSamplingFrequencies() 
     522{ 
     523    std::vector<int> frequencies; 
     524    frequencies.push_back(44100); 
     525    frequencies.push_back(48000); 
     526    frequencies.push_back(88200); 
     527    frequencies.push_back(96000); 
     528    frequencies.push_back(176400); 
     529    frequencies.push_back(192000); 
     530    return frequencies; 
     531} 
     532 
    515533uint16_t 
    516534SaffireProDevice::getConfigurationIdSyncMode() 
     
    524542} 
    525543 
     544uint64_t 
     545SaffireProDevice::getConfigurationId() 
     546{ 
     547    // have the generic mechanism create a unique configuration id. 
     548    uint64_t id = BeBoB::AvDevice::getConfigurationId(); 
     549 
     550    // there are some parts that can be enabled/disabled and 
     551    // that have influence on the AV/C model and channel config 
     552    // so add them to the config id 
     553    #if 0 
     554    // FIXME: doesn't seem to be working, but the channel count 
     555    //        makes that it's not that important 
     556    if(getEnableDigitalChannel(eDC_SPDIF)) { 
     557        id |= 1ULL << 40; 
     558    } 
     559    if(isPro26()) { 
     560        if(getEnableDigitalChannel(eDC_ADAT1)) { 
     561            id |= 1ULL << 41; 
     562        } 
     563        if(getEnableDigitalChannel(eDC_ADAT2)) { 
     564            id |= 1ULL << 42; 
     565        } 
     566    } 
     567    #endif 
     568    return id; 
     569} 
     570 
    526571bool 
    527572SaffireProDevice::setNickname( std::string name) 
     
    538583        return m_deviceNameControl->getValue(); 
    539584    } else return "Unknown"; 
     585} 
     586 
     587bool 
     588SaffireProDevice::canChangeNickname() 
     589{ 
     590    return true; 
    540591} 
    541592 
     
    662713 
    663714                    // the device needs quite some time to reboot 
    664                     Util::SystemTimeSource::SleepUsecRelative(2 * 1000 * 1000); 
     715                    Util::SystemTimeSource::SleepUsecRelative(6 * 1000 * 1000); 
    665716 
    666717                    // wait for the device to finish the reboot 
     
    692743                Util::SystemTimeSource::SleepUsecRelative(1 * 1000 * 1000); 
    693744 
     745                // update the generation of the 1394 service 
     746                get1394Service().updateGeneration(); 
     747 
     748                // update our config rom since it might have changed 
     749                // if this fails it means we have disappeared from the bus 
     750                // that's bad. 
     751                if(!getConfigRom().updatedNodeId()) { 
     752                    debugError("Could not update node id\n"); 
     753                    getDeviceManager().unlockBusResetHandler(); 
     754                    return false; 
     755                } 
     756 
    694757                // we have to rediscover the device 
    695758                if (discover()) break; 
     
    719782            return false; 
    720783        } 
    721  
    722784        return true; 
    723785    } 
    724786    // not executable 
    725787    return false; 
    726  
    727788} 
    728789 
     
    756817void 
    757818SaffireProDevice::flashLed() { 
    758     int ledFlashDuration=2; 
     819    int ledFlashDuration = 2; 
    759820    if(!getOption("ledFlashDuration", ledFlashDuration)) { 
    760         debugWarning("Could not retrieve ledFlashDuration parameter, defaulting to 2sec\n"); 
    761     } 
    762     int ledFlashFrequency=10; 
     821        debugOutput( DEBUG_LEVEL_VERBOSE, "Could not retrieve ledFlashDuration parameter, defaulting to 2sec\n"); 
     822    } 
     823    int ledFlashFrequency = 10; 
    763824    if(!getOption("ledFlashFrequency", ledFlashFrequency)) { 
    764         debugWarning("Could not retrieve ledFlashFrequency parameter, defaulting to 10Hz\n"); 
    765     } 
    766  
    767     uint32_t reg=0; 
     825        debugOutput( DEBUG_LEVEL_VERBOSE, "Could not retrieve ledFlashFrequency parameter, defaulting to 10Hz\n"); 
     826    } 
     827 
     828    uint32_t reg = 0; 
    768829    debugOutput( DEBUG_LEVEL_VERBOSE, "flashing led ...\n" ); 
    769830     
     
    863924                     "PLL lock range: %d\n", retval ); 
    864925    return retval; 
     926} 
     927 
     928bool 
     929SaffireProDevice::isMidiEnabled() { 
     930    uint32_t ready; 
     931    if ( !getSpecificValue(FR_SAFFIREPRO_CMD_ID_AVC_MODEL_MIDI, &ready ) ) { 
     932        debugError( "getSpecificValue failed\n" ); 
     933        return false; 
     934    } 
     935 
     936    debugOutput( DEBUG_LEVEL_VERBOSE, 
     937                     "isMidiEnabled: %d\n", ready != 0 ); 
     938    return ready != 0; 
    865939} 
    866940 
  • trunk/libffado/src/bebob/focusrite/focusrite_saffirepro.h

    r1336 r1498  
    158158#define FR_SAFFIREPRO_CMD_SWITCH_CONFIG_MUTE910  (1<<8) 
    159159 
    160 #define FR_SAFFIREPRO_CMD_ID_FRONT_DIAL             86 
     160#define FR_SAFFIREPRO_CMD_ID_MONITOR_DIAL           86 
    161161#define FR_SAFFIREPRO_CMD_ID_DIM_INDICATOR          87 
    162162#define FR_SAFFIREPRO_CMD_ID_MUTE_INDICATOR         88 
     
    168168#define FR_SAFFIREPRO_CMD_ID_USING_HIGHVOLTAGE_RAIL 92 
    169169 
     170#define FR_SAFFIREPRO_CMD_ID_SYNC_CONFIG_MASK  0x000000FF 
     171#define FR_SAFFIREPRO_CMD_ID_SYNC_LOCK_MASK    0x0000FF00 
    170172#define FR_SAFFIREPRO_CMD_ID_SYNC_CONFIG            93 
    171173#define FR_SAFFIREPRO_CMD_SYNC_CONFIG_INTERNAL       0 
     
    363365    virtual bool setSamplingFrequency( int ); 
    364366    virtual int getSamplingFrequency( ); 
     367    virtual std::vector<int> getSupportedSamplingFrequencies(); 
    365368 
    366369    virtual bool buildMixer(); 
     
    369372    virtual std::string getNickname(); 
    370373    virtual bool setNickname(std::string name); 
     374    virtual bool canChangeNickname(); 
    371375protected: 
    372376    void rebootDevice(); 
    373377    void flashLed(); 
    374378    bool isAudioOn(); 
     379    bool isMidiEnabled(); 
    375380    bool isExtClockLocked(); 
    376381    uint32_t getCount32(); 
     
    409414protected: 
    410415    virtual uint16_t getConfigurationIdSyncMode(); 
     416    virtual uint64_t getConfigurationId(); 
    411417 
    412418private: 
  • trunk/libffado/src/bebob/mackie/onyxmixer.cpp

    r1210 r1498  
    4141    debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::Mackie::OnyxMixerDevice (NodeID %d)\n", 
    4242                 getConfigRom().getNodeId() ); 
    43  
    44     // needs a lot of time 
    45     if (AVC::AVCCommand::getSleepAfterAVCCommand() < 1000) { 
    46         AVC::AVCCommand::setSleepAfterAVCCommand( 1000 ); 
    47     } 
    4843} 
    4944 
  • trunk/libffado/src/bebob/terratec/terratec_cmd.h

    r864 r1498  
    2828#include "libutil/cmd_serialize.h" 
    2929#include "libavc/general/avc_vendor_dependent_cmd.h" 
    30  
    31 #include <libavc1394/avc1394.h> 
    3230 
    3331namespace BeBoB { 
  • trunk/libffado/src/devicemanager.cpp

    r1336 r1498  
    195195        m_1394Services.push_back(tmp1394Service); 
    196196 
     197        if(!tmp1394Service->useConfiguration(m_configuration)) { 
     198            debugWarning("Could not load config to 1394service\n"); 
     199        } 
     200 
    197201        tmp1394Service->setThreadParameters(m_thread_realtime, m_thread_priority); 
    198202        if ( !tmp1394Service->initialize( port ) ) { 
     
    468472 
    469473    if (!slaveMode) { 
     474        // for the devices that are still in the list check if they require re-discovery 
     475        FFADODeviceVector failed_to_rediscover; 
     476        for ( FFADODeviceVectorIterator it_dev = m_avDevices.begin(); 
     477            it_dev != m_avDevices.end(); 
     478            ++it_dev ) 
     479        { 
     480            FFADODevice* avDevice = *it_dev; 
     481            if(avDevice->needsRediscovery()) { 
     482                debugOutput( DEBUG_LEVEL_NORMAL, 
     483                             "Device with GUID %s requires rediscovery (state changed)...\n", 
     484                             avDevice->getConfigRom().getGuidString().c_str()); 
     485 
     486                bool isFromCache = false; 
     487                if ( useCache && avDevice->loadFromCache() ) { 
     488                    debugOutput( DEBUG_LEVEL_VERBOSE, "could load from cache\n" ); 
     489                    isFromCache = true; 
     490                    // restore the debug level for everything that was loaded 
     491                    avDevice->setVerboseLevel( getDebugLevel() ); 
     492                } else if ( avDevice->discover() ) { 
     493                    debugOutput( DEBUG_LEVEL_VERBOSE, "discovery successful\n" ); 
     494                } else { 
     495                    debugError( "could not discover device\n" ); 
     496                    failed_to_rediscover.push_back(avDevice); 
     497                    continue; 
     498                } 
     499                if ( !isFromCache && !avDevice->saveCache() ) { 
     500                    debugOutput( DEBUG_LEVEL_VERBOSE, "No cached version of AVC model created\n" ); 
     501                } 
     502            } else { 
     503                debugOutput( DEBUG_LEVEL_NORMAL, 
     504                             "Device with GUID %s does not require rediscovery...\n", 
     505                             avDevice->getConfigRom().getGuidString().c_str()); 
     506            } 
     507        } 
     508        // remove devices that failed to rediscover 
     509        // FIXME: surely there has to be a better way to do this 
     510        FFADODeviceVector to_keep; 
     511        for ( FFADODeviceVectorIterator it = m_avDevices.begin(); 
     512            it != m_avDevices.end(); 
     513            ++it ) 
     514        { 
     515            bool keep_this_device = true; 
     516            for ( FFADODeviceVectorIterator it2 = failed_to_rediscover.begin(); 
     517                it2 != failed_to_rediscover.end(); 
     518                ++it2 ) 
     519            { 
     520                if(*it == *it2) { 
     521                    debugOutput( DEBUG_LEVEL_NORMAL, 
     522                                "Removing device with GUID %s due to failed discovery...\n", 
     523                                (*it)->getConfigRom().getGuidString().c_str()); 
     524                    keep_this_device = false; 
     525                    break; 
     526                } 
     527            } 
     528            if(keep_this_device) { 
     529                to_keep.push_back(*it); 
     530            } 
     531        } 
     532        for ( FFADODeviceVectorIterator it2 = failed_to_rediscover.begin(); 
     533            it2 != failed_to_rediscover.end(); 
     534            ++it2 ) 
     535        { 
     536            if (!deleteElement(*it2)) { 
     537                debugWarning("failed to remove AvDevice from Control::Container\n"); 
     538            } 
     539            delete *it2; 
     540        } 
     541        m_avDevices = to_keep; 
     542 
     543        // pick up new devices 
    470544        for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin(); 
    471545            it != m_1394Services.end(); 
     
    499573 
    500574                bool already_in_vector = false; 
    501                 for ( FFADODeviceVectorIterator it = m_avDevices.begin(); 
    502                     it != m_avDevices.end(); 
    503                     ++it
     575                for ( FFADODeviceVectorIterator it_dev = m_avDevices.begin(); 
     576                    it_dev != m_avDevices.end(); 
     577                    ++it_dev
    504578                { 
    505                     if ((*it)->getConfigRom().getGuid() == configRom->getGuid()) { 
     579                    if ((*it_dev)->getConfigRom().getGuid() == configRom->getGuid()) { 
    506580                        already_in_vector = true; 
    507581                        break; 
     
    713787            getSyncSource()); 
    714788    } 
     789 
    715790    return true; 
    716791} 
  • trunk/libffado/src/dice/dice_avdevice.cpp

    r1347 r1498  
    5656    {FW_VENDORID_TCAT,   0x00000023, "TC Electronic", "Konnekt Live"}, 
    5757    {FW_VENDORID_ALESIS, 0x00000001, "Alesis", "io|14"}, 
     58    {FW_VENDORID_PRESONUS, 0x0000000b, "Presonus", "Firestudio Project"}, 
    5859}; 
    5960 
  • trunk/libffado/src/ffado.cpp

    r1336 r1498  
    7676} 
    7777 
    78 // FIXME: this should be cleaned up 
    79 #include "libavc/general/avc_generic.h" 
    80 void ffado_sleep_after_avc_command( int time ) 
    81 { 
    82     AVC::AVCCommand::setSleepAfterAVCCommand( time ); 
    83 } 
    84  
    8578struct _ffado_device 
    8679{ 
     
    120113 
    121114    dev->m_deviceManager->setVerboseLevel(dev->options.verbose); 
     115 
     116    if(dev->options.realtime) { 
     117        debugOutput(DEBUG_LEVEL_VERBOSE, 
     118                    "Starting with realtime scheduling, base priority %d\n",  
     119                    dev->options.packetizer_priority); 
     120    } else { 
     121        debugWarning("Realtime scheduling is not enabled. This will cause significant reliability issues.\n"); 
     122    } 
    122123    dev->m_deviceManager->setThreadParameters(dev->options.realtime, dev->options.packetizer_priority); 
    123124 
  • trunk/libffado/src/ffadodevice.cpp

    r1217 r1498  
    7474            debugWarning("failed to add Nickname control to container\n"); 
    7575        } 
     76        // add a generic control for the streaming status 
     77        if(!m_genericContainer->addElement(new Control::StreamingStatus(*this))) { 
     78            debugWarning("failed to add StreamingStatus control to container\n"); 
     79        } 
    7680    } 
    7781} 
     
    144148} 
    145149 
     150bool 
     151FFADODevice::needsRediscovery() 
     152{ 
     153    // require rediscovery by default 
     154    return true; 
     155} 
     156 
    146157enum FFADODevice::eSyncState 
    147158FFADODevice::getSyncState( ) { 
    148159    return eSS_Unknown; 
     160} 
     161 
     162enum FFADODevice::eStreamingState 
     163FFADODevice::getStreamingState() 
     164{ 
     165    return eSS_Idle; 
    149166} 
    150167 
     
    172189FFADODevice::getNickname() 
    173190{ 
    174     return "Unknown"; 
     191    return "Unsupported"; 
     192
     193 
     194bool 
     195FFADODevice::canChangeNickname() 
     196
     197    return false; 
    175198} 
    176199 
  • trunk/libffado/src/ffadodevice.h

    r1336 r1498  
    103103     */ 
    104104    virtual bool saveCache(); 
     105 
     106    /** 
     107     * @brief Called by DeviceManager to check whether a device requires rediscovery 
     108     * 
     109     * This function is called to figure out if the device has to be rediscovered 
     110     * e.g. after a bus reset where the device internal structure changed. 
     111     * 
     112     * @returns true if device requires rediscovery 
     113     */ 
     114    virtual bool needsRediscovery(); 
    105115 
    106116    /** 
     
    251261 
    252262    /** 
     263     * @brief stream states 
     264     */ 
     265    enum eStreamingState { 
     266        eSS_Idle = 0,        ///> not streaming 
     267        eSS_Sending = 1,     ///> the device is sending a stream 
     268        eSS_Receiving = 2,   ///> the device is receiving a stream 
     269        eSS_Both = 3,        ///> the device is sending and receiving a stream 
     270    }; 
     271 
     272    /** 
     273     * @brief gets the devices current synchronization state 
     274     * @return the device's sync state 
     275     */ 
     276    virtual enum eStreamingState getStreamingState(); 
     277 
     278    /** 
    253279     * @brief This is called by the device manager to give the device a unique ID. 
    254280     * 
     
    438464 
    439465    /** 
     466     * @brief return whether the nick name of this device can be changed 
     467     * 
     468     * @return true if the nick can be changed 
     469     */ 
     470    virtual bool canChangeNickname(); 
     471 
     472    /** 
    440473     * @brief handle a bus reset 
    441474     * 
  • trunk/libffado/src/fireworks/efc/efc_avc_cmd.h

    r864 r1498  
    2929#include "libavc/general/avc_vendor_dependent_cmd.h" 
    3030 
    31 #include <libavc1394/avc1394.h> 
    32  
    3331#include "efc_cmd.h" 
    3432 
  • trunk/libffado/src/genericavc/avc_avdevice.cpp

    r1336 r1498  
    164164    AVC::Unit::setVerboseLevel(l); 
    165165    debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l ); 
     166} 
     167 
     168#include <libieee1394/IEC61883.h> 
     169enum FFADODevice::eStreamingState 
     170AvDevice::getStreamingState() 
     171{ 
     172    // check the IEC plug control registers to see if the device is streaming 
     173    // a bit of a hack, but will do until we come up with something better 
     174    struct iec61883_oPCR oPCR0; 
     175    struct iec61883_iPCR iPCR0; 
     176     
     177    quadlet_t *oPCR0q = (quadlet_t *)&oPCR0; 
     178    quadlet_t *iPCR0q = (quadlet_t *)&iPCR0; 
     179     
     180    if(!get1394Service().read(getNodeId() | 0xFFC0, CSR_REGISTER_BASE + CSR_O_PCR_0, 1, oPCR0q)) { 
     181        debugWarning("Could not read oPCR0 register\n"); 
     182    } 
     183    if(!get1394Service().read(getNodeId() | 0xFFC0, CSR_REGISTER_BASE + CSR_I_PCR_0, 1, iPCR0q)) { 
     184        debugWarning("Could not read iPCR0 register\n"); 
     185    } 
     186 
     187    *oPCR0q = CondSwapFromBus32(*oPCR0q); 
     188    *iPCR0q = CondSwapFromBus32(*iPCR0q); 
     189 
     190    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "iPCR0: %08X, oPCR0: %08X\n", *iPCR0q, *oPCR0q); 
     191 
     192    if(iPCR0.n_p2p_connections > 0 && oPCR0.n_p2p_connections > 0) { 
     193        return eSS_Both; 
     194    } else if (iPCR0.n_p2p_connections > 0) { 
     195        return eSS_Receiving; 
     196    } else if (oPCR0.n_p2p_connections > 0) { 
     197        return eSS_Sending; 
     198    } else { 
     199        return eSS_Idle; 
     200    } 
    166201} 
    167202 
  • trunk/libffado/src/genericavc/avc_avdevice.h

    r1336 r1498  
    7474    virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i); 
    7575 
     76    virtual enum eStreamingState getStreamingState(); 
     77 
    7678    virtual bool prepare(); 
    7779    virtual bool lock(); 
  • trunk/libffado/src/libavc/audiosubunit/avc_function_block.h

    r1361 r1498  
    2828#include "../general/avc_generic.h" 
    2929 
    30 #include <libavc1394/avc1394.h> 
    3130#include <vector> 
    3231using namespace std; 
  • trunk/libffado/src/libavc/avc_definitions.h

    r1234 r1498  
    2525#define AVCDEFINITIONS_H 
    2626 
    27 #include <libavc1394/avc1394.h> 
    2827#include <cstring> 
    2928#include <cstdlib> 
    3029#include <ostream> 
    31  
     30#include <libraw1394/raw1394.h> 
    3231 
    3332namespace AVC { 
     
    8887typedef quadlet_t company_id_t; 
    8988 
    90 #define AVC1394_SUBUNIT_AUDIO 1 
    91 #define AVC1394_SUBUNIT_PRINTER 2 
    92 #define AVC1394_SUBUNIT_CA 6 
    93 #define AVC1394_SUBUNIT_PANEL 9 
    94 #define AVC1394_SUBUNIT_BULLETIN_BOARD 0xA 
    95 #define AVC1394_SUBUNIT_CAMERA_STORAGE 0xB 
    96 #define AVC1394_SUBUNIT_MUSIC 0xC 
    97 #define AVC1394_SUBUNIT_RESERVED 0x1D 
     89enum ESubunitType { 
     90    eST_Monitor       = 0x00, 
     91    eST_Audio         = 0x01, 
     92    eST_Printer       = 0x02, 
     93    eST_Disc          = 0x03, 
     94    eST_VCR           = 0x04, 
     95    eST_Tuner         = 0x05, 
     96    eST_CA            = 0x06, 
     97    eST_Camera        = 0x07, 
     98    eST_Panel         = 0x09, 
     99    eST_BulltinBoard  = 0x0A, 
     100    eST_CameraStorage = 0x0B, 
     101    eST_Music         = 0x0C, 
     102    eST_VendorUnique  = 0x1C, 
     103    eST_Reserved      = 0x1D, 
     104    eST_Extended      = 0x1E, 
     105    eST_Unit          = 0x1F, 
     106}; 
    98107 
    99108#define AVC1394_SUBUNIT_ID_RESERVED 0x06 
    100  
    101 enum ESubunitType { 
    102     eST_Monitor       = AVC1394_SUBUNIT_VIDEO_MONITOR, 
    103     eST_Audio         = AVC1394_SUBUNIT_AUDIO, 
    104     eST_Printer       = AVC1394_SUBUNIT_PRINTER, 
    105     eST_Disc          = AVC1394_SUBUNIT_DISC_RECORDER, 
    106     eST_VCR           = AVC1394_SUBUNIT_VCR, 
    107     eST_Tuner         = AVC1394_SUBUNIT_TUNER, 
    108     eST_CA            = AVC1394_SUBUNIT_CA, 
    109     eST_Camera        = AVC1394_SUBUNIT_VIDEO_CAMERA, 
    110     eST_Panel         = AVC1394_SUBUNIT_PANEL, 
    111     eST_BulltinBoard  = AVC1394_SUBUNIT_BULLETIN_BOARD, 
    112     eST_CameraStorage = AVC1394_SUBUNIT_CAMERA_STORAGE, 
    113     eST_Music         = AVC1394_SUBUNIT_MUSIC, 
    114     eST_VendorUnique  = AVC1394_SUBUNIT_VENDOR_UNIQUE, 
    115     eST_Reserved      = AVC1394_SUBUNIT_RESERVED, 
    116     eST_Extended      = AVC1394_SUBUNIT_EXTENDED, 
    117     eST_Unit          = AVC1394_SUBUNIT_UNIT, 
    118 }; 
    119109 
    120110enum ESubunitType byteToSubunitType(byte_t s); 
  • trunk/libffado/src/libavc/ccm/avc_signal_source.cpp

    r1135 r1498  
    6868 
    6969SignalSubunitAddress::SignalSubunitAddress() 
    70     : m_subunitType( AVC1394_SUBUNIT_RESERVED
     70    : m_subunitType( eST_Reserved
    7171    , m_subunitId( AVC1394_SUBUNIT_ID_RESERVED ) 
    7272    , m_plugId( ePI_Invalid ) 
  • trunk/libffado/src/libavc/ccm/avc_signal_source.h

    r1239 r1498  
    2727#include "../general/avc_generic.h" 
    2828#include "../avc_definitions.h" 
    29  
    30 #include <libavc1394/avc1394.h> 
    3129 
    3230namespace AVC { 
  • trunk/libffado/src/libavc/descriptors/avc_descriptor.h

    r1361 r1498  
    4141#include "debugmodule/debugmodule.h" 
    4242 
    43 #include <libavc1394/avc1394.h> 
    4443#include <string> 
    4544 
  • trunk/libffado/src/libavc/descriptors/avc_descriptor_cmd.h

    r864 r1498  
    2727#include "../general/avc_generic.h" 
    2828 
    29 #include <libavc1394/avc1394.h> 
    30  
    3129namespace AVC { 
    3230 
     31#define AVC1394_CMD_OPEN_DESCRIPTOR         0x08 
     32#define AVC1394_CMD_READ_DESCRIPTOR         0x09 
     33#define AVC1394_CMD_WRITE_DESCRIPTOR        0x0A 
     34#define AVC1394_CMD_SEARCH_DESCRIPTOR       0x0B 
     35#define AVC1394_CMD_OBJECT_NUMBER_SELECT    0x0D 
    3336 
    34 // defined in avc1394.h 
    35 // #define AVC1394_CMD_OPEN_DESCRIPTOR         0x08 
    36 // #define AVC1394_CMD_READ_DESCRIPTOR         0x09 
    37 // #define AVC1394_CMD_WRITE_DESCRIPTOR        0x0A 
    38 // #define AVC1394_CMD_SEARCH_DESCRIPTOR       0x0B 
    39 // #define AVC1394_CMD_OBJECT_NUMBER_SELECT    0x0D 
    40  
    41 // not yet defined 
    4237#define AVC1394_CMD_CREATE_DESCRIPTOR       0x0C 
    4338#define AVC1394_CMD_OPEN_INFOBLOCK          0x05 
  • trunk/libffado/src/libavc/general/avc_connect.h

    r864 r1498  
    2727#include "avc_generic.h" 
    2828 
    29 #include <libavc1394/avc1394.h> 
     29#define AVC1394_CMD_CONNECT 0x24 
     30 
    3031namespace AVC { 
    3132 
  • trunk/libffado/src/libavc/general/avc_extended_plug_info.h

    r864 r1498  
    2828#include "avc_generic.h" 
    2929 
    30 #include <libavc1394/avc1394.h> 
    31  
    3230#include <string> 
    3331#include <vector> 
     32 
     33#define AVC1394_CMD_PLUG_INFO 0x02 
    3434 
    3535namespace AVC { 
  • trunk/libffado/src/libavc/general/avc_extended_subunit_info.h

    r864 r1498  
    2727#include "avc_generic.h" 
    2828 
    29 #include <libavc1394/avc1394.h> 
    30  
    3129#include <string> 
    3230#include <vector> 
     31 
     32#define AVC1394_CMD_SUBUNIT_INFO 0x31 
    3333 
    3434namespace AVC { 
  • trunk/libffado/src/libavc/general/avc_generic.cpp

    r1234 r1498  
    4242IMPL_DEBUG_MODULE( AVCCommand, AVCCommand, DEBUG_LEVEL_NORMAL ); 
    4343IMPL_DEBUG_MODULE( IBusData, IBusData, DEBUG_LEVEL_VERBOSE ); 
    44  
    45 int AVCCommand::m_time = 0; 
    4644 
    4745AVCCommand::AVCCommand( Ieee1394Service& ieee1394service, 
     
    213211    } 
    214212 
     213    bool result = false; 
    215214    unsigned int resp_len; 
    216215    quadlet_t* resp = m_p1394Service->transactionBlock( m_nodeId, 
     
    218217                                                        ( fcpFrameSize+3 ) / 4, 
    219218                                                        &resp_len ); 
    220     bool result = false; 
    221219    if ( resp ) { 
    222220        resp_len *= 4; 
     
    226224        switch ( m_eResponse ) 
    227225        { 
    228         case eR_Accepted: 
    229         case eR_Implemented: 
    230         case eR_Rejected: 
    231         case eR_NotImplemented: 
    232         { 
    233             Util::Cmd::BufferDeserialize de( buf, resp_len ); 
    234             result = deserialize( de ); 
    235  
    236             debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE,"  Response:\n"); 
    237             showFcpFrame( buf, de.getNrOfConsumedBytes() ); 
    238  
    239             Util::Cmd::StringSerializer se_dbg; 
    240             serialize( se_dbg ); 
    241  
    242             // output the debug message in smaller chunks to avoid problems 
    243             // with a max message size 
    244             unsigned int chars_to_write=se_dbg.getString().size(); 
    245             unsigned int chars_written=0; 
    246             while (chars_written<chars_to_write) { 
    247                 debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "%s\n", 
    248                             se_dbg.getString().substr(chars_written, DEBUG_MAX_MESSAGE_LENGTH).c_str()); 
    249                 chars_written += DEBUG_MAX_MESSAGE_LENGTH-1; 
     226            case eR_Accepted: 
     227            case eR_Implemented: 
     228            case eR_Rejected: 
     229            case eR_NotImplemented: 
     230            { 
     231                Util::Cmd::BufferDeserialize de( buf, resp_len ); 
     232                result = deserialize( de ); 
     233     
     234                debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE,"  Response:\n"); 
     235                showFcpFrame( buf, de.getNrOfConsumedBytes() ); 
     236     
     237                Util::Cmd::StringSerializer se_dbg; 
     238                serialize( se_dbg ); 
     239     
     240                // output the debug message in smaller chunks to avoid problems 
     241                // with a max message size 
     242                unsigned int chars_to_write=se_dbg.getString().size(); 
     243                unsigned int chars_written=0; 
     244                while (chars_written<chars_to_write) { 
     245                    debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "%s\n", 
     246                                se_dbg.getString().substr(chars_written, DEBUG_MAX_MESSAGE_LENGTH).c_str()); 
     247                    chars_written += DEBUG_MAX_MESSAGE_LENGTH-1; 
     248                } 
    250249            } 
     250            break; 
     251            default: 
     252                debugWarning( "unexpected response received (0x%x)\n", m_eResponse ); 
     253                debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE,"  Response:\n"); 
     254     
     255                Util::Cmd::BufferDeserialize de( buf, resp_len ); 
     256                deserialize( de ); 
     257     
     258                showFcpFrame( buf, de.getNrOfConsumedBytes() ); 
     259                result = false; 
    251260 
    252261        } 
    253         break; 
    254         default: 
    255             debugWarning( "unexpected response received (0x%x)\n", m_eResponse ); 
    256             debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE,"  Response:\n"); 
    257  
    258             Util::Cmd::BufferDeserialize de( buf, resp_len ); 
    259             deserialize( de ); 
    260  
    261             showFcpFrame( buf, de.getNrOfConsumedBytes() ); 
    262  
    263         } 
     262        debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE, "\n" ); 
     263        m_p1394Service->transactionBlockClose(); 
    264264    } else { 
    265        debugWarning( "no response\n" ); 
    266     } 
    267  
    268     debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE, "\n" ); 
    269  
    270     m_p1394Service->transactionBlockClose(); 
    271  
    272     SleepRelativeUsec( m_time ); 
     265        debugOutput( DEBUG_LEVEL_VERBOSE, "no response\n" ); 
     266        result = false; 
     267        m_p1394Service->transactionBlockClose(); 
     268    } 
    273269 
    274270    return result; 
    275 } 
    276  
    277 void 
    278 AVCCommand::setSleepAfterAVCCommand( int time ) 
    279 { 
    280     m_time = time; 
    281271} 
    282272 
  • trunk/libffado/src/libavc/general/avc_generic.h

    r864 r1498  
    2929 
    3030#include "fbtypes.h" 
    31  
    32 #include <libavc1394/avc1394.h> 
    3331 
    3432class Ieee1394Service; 
     
    7068public: 
    7169    enum EResponse { 
    72         eR_Unknown        = 0
    73         eR_NotImplemented = AVC1394_RESP_NOT_IMPLEMENTED
    74         eR_Accepted       = AVC1394_RESP_ACCEPTED
    75         eR_Rejected       = AVC1394_RESP_REJECTED
    76         eR_InTransition   = AVC1394_RESP_IN_TRANSITION
    77         eR_Implemented    = AVC1394_RESP_IMPLEMENTED
    78         eR_Changed        = AVC1394_RESP_CHANGED, 
    79         eR_Interim        = AVC1394_RESP_INTERIM
     70        eR_Unknown        = 0xff
     71        eR_NotImplemented = 0x08
     72        eR_Accepted       = 0x09
     73        eR_Rejected       = 0x0A
     74        eR_InTransition   = 0x0B
     75        eR_Implemented    = 0x0C
     76        eR_Changed        = 0x0D, 
     77        eR_Interim        = 0x0F
    8078    }; 
    8179 
    8280    enum ECommandType { 
    83         eCT_Control         = AVC1394_CTYP_CONTROL
    84         eCT_Status          = AVC1394_CTYP_STATUS
    85         eCT_SpecificInquiry = AVC1394_CTYP_SPECIFIC_INQUIRY
    86         eCT_Notify          = AVC1394_CTYP_NOTIFY
    87         eCT_GeneralInquiry  = AVC1394_CTYP_GENERAL_INQUIRY
     81        eCT_Control         = 0x00
     82        eCT_Status          = 0x01
     83        eCT_SpecificInquiry = 0x02
     84        eCT_Notify          = 0x03
     85        eCT_GeneralInquiry  = 0x04
    8886        eCT_Unknown         = 0xff, 
    8987    }; 
     
    112110    virtual const char* getCmdName() const = 0; 
    113111 
    114     // workaround 
    115     static void setSleepAfterAVCCommand( int time ); 
    116     static int getSleepAfterAVCCommand( ) {return m_time;}; 
    117112protected: 
    118113    void showFcpFrame( const unsigned char* buf, 
     
    136131    EResponse    m_eResponse; 
    137132    ECommandType m_commandType; 
    138     static int   m_time; 
    139      
     133 
    140134protected: 
    141135    DECLARE_DEBUG_MODULE; 
  • trunk/libffado/src/libavc/general/avc_plug.cpp

    r1336 r1498  
    267267Plug::discoverPlugType() 
    268268{ 
    269  
    270269    return true; 
    271270} 
     
    541540    debugOutput( DEBUG_LEVEL_VERBOSE, "Discovering incoming connections...\n"); 
    542541 
     542    m_inputConnections.clear(); 
    543543    int sourcePlugGlobalId=getSignalSource(); 
    544544 
     
    19901990PlugManager::tidyPlugConnections(PlugConnectionVector& connections) 
    19911991{ 
     1992    connections.clear(); 
    19921993    for ( PlugVector::const_iterator it = m_plugs.begin(); 
    19931994          it !=  m_plugs.end(); 
  • trunk/libffado/src/libavc/general/avc_plug_info.h

    r864 r1498  
    2727#include "avc_generic.h" 
    2828 
    29 #include <libavc1394/avc1394.h> 
     29#define AVC1394_CMD_PLUG_INFO 0x02 
    3030 
    3131#define AVC1394_PLUG_INFO_SUBFUNCTION_SERIAL_BUS_ISOCHRONOUS_AND_EXTERNAL_PLUG 0x00 
  • trunk/libffado/src/libavc/general/avc_signal_format.cpp

    r1135 r1498  
    2828#include "libutil/ByteSwap.h" 
    2929#include <iostream> 
     30 
     31#define AVC1394_CMD_INPUT_PLUG_SIGNAL_FORMAT 0x19 
     32#define AVC1394_CMD_OUTPUT_PLUG_SIGNAL_FORMAT 0x18 
    3033 
    3134using namespace std; 
  • trunk/libffado/src/libavc/general/avc_signal_format.h

    r864 r1498  
    2727 
    2828#include "avc_generic.h" 
    29  
    30 #include <libavc1394/avc1394.h> 
    3129 
    3230namespace AVC { 
  • trunk/libffado/src/libavc/general/avc_subunit_info.h

    r864 r1498  
    2727#include "avc_generic.h" 
    2828 
    29 #include <libavc1394/avc1394.h> 
    30  
     29#define AVC1394_CMD_SUBUNIT_INFO 0x31 
    3130 
    3231namespace AVC { 
  • trunk/libffado/src/libavc/general/avc_unit.cpp

    r1336 r1498  
    4848Unit::Unit( ) 
    4949    : m_pPlugManager( new PlugManager( ) ) 
    50     , m_activeSyncInfo( 0 ) 
    5150{ 
    5251    debugOutput( DEBUG_LEVEL_VERBOSE, "Created Unit\n" ); 
     
    163162    m_syncInfos.clear(); 
    164163 
    165     m_activeSyncInfo = NULL; 
    166  
    167164    return true; 
    168165} 
     
    171168Unit::discover() 
    172169{ 
    173  
     170    debugOutput( DEBUG_LEVEL_VERBOSE, "Discovering AVC::Unit...\n"); 
    174171    if( !clean() ) { 
    175172        debugError( "Could not clean unit data structures\n" ); 
     
    187184    } 
    188185 
     186    if ( !rediscoverConnections() ) { 
     187        debugError( "Detecting connections failed\n" ); 
     188        return false; 
     189    } 
     190 
     191    if ( !discoverSyncModes() ) { 
     192        debugError( "Detecting sync modes failed\n" ); 
     193        return false; 
     194    } 
     195 
     196    if ( !propagatePlugInfo() ) { 
     197        debugError( "Failed to propagate plug info\n" ); 
     198        return false; 
     199    } 
     200 
     201    return true; 
     202} 
     203 
     204bool 
     205Unit::rediscoverConnections() { 
     206    debugOutput( DEBUG_LEVEL_VERBOSE, "Re-discovering plug connections...\n"); 
     207 
     208    // clear the previous connections 
     209    for ( PlugConnectionVector::iterator it = m_plugConnections.begin(); 
     210          it != m_plugConnections.end(); 
     211          ++it ) 
     212    { 
     213        delete *it; 
     214    } 
     215    m_plugConnections.clear(); 
     216 
    189217    if ( !discoverPlugConnections() ) { 
    190218        debugError( "Detecting plug connections failed\n" ); 
     
    201229        return false; 
    202230    } 
    203  
    204     if ( !discoverSyncModes() ) { 
    205         debugError( "Detecting sync modes failed\n" ); 
    206         return false; 
    207     } 
    208  
    209     if ( !propagatePlugInfo() ) { 
    210         debugError( "Failed to propagate plug info\n" ); 
    211         return false; 
    212     } 
    213  
    214231    return true; 
    215232} 
     
    717734    showPlugs( syncMSUOutputPlugs ); 
    718735 
     736    m_syncInfos.clear(); 
    719737    // Currently there is no usable setup for sync streams. 
    720738    // There is no point in wasting time here. Let's skip 
     
    745763                                      "Digital Input Sync" ); 
    746764 
    747     return updateActiveSyncInfo(); 
    748 
    749  
    750 bool 
    751 Unit::updateActiveSyncInfo() 
    752 
     765    return true; 
     766
     767 
     768const Unit::SyncInfo* 
     769Unit::getActiveSyncInfo() 
     770
     771    SyncInfo* activeSyncInfo = NULL; 
    753772    PlugVector syncMSUInputPlugs = m_pPlugManager->getPlugsByType( 
    754773        eST_Music, 
     
    785804                     && ( pSyncInfo->m_destination == msuPlug ) ) 
    786805                { 
    787                     m_activeSyncInfo = pSyncInfo; 
     806                    activeSyncInfo = pSyncInfo; 
    788807                    break; 
    789808                } 
    790809            } 
    791             if(m_activeSyncInfo) { 
     810            if(activeSyncInfo) { 
    792811                debugOutput( DEBUG_LEVEL_NORMAL, 
    793812                            "Active Sync Connection: %s, '%s' -> '%s'\n", 
    794                             m_activeSyncInfo->m_description.c_str(), 
     813                            activeSyncInfo->m_description.c_str(), 
    795814                            plug->getName(), 
    796815                            msuPlug->getName() ); 
     
    798817        } 
    799818    } 
    800     return true
     819    return activeSyncInfo
    801820} 
    802821 
     
    831850bool Unit::setActiveSync(const SyncInfo& syncInfo) 
    832851{ 
    833     bool result = true; 
     852    bool retval = true; 
     853 
     854    if ( ! syncInfo.m_source->inquireConnnection( *syncInfo.m_destination ) ) { 
     855        // this should not happen 
     856        debugError("Sync connection '%s' -> '%s' not possible. This might be a bug.\n", 
     857                   syncInfo.m_source->getName(), syncInfo.m_destination->getName()); 
     858    } 
    834859 
    835860    if(!syncInfo.m_source->setConnection( *syncInfo.m_destination )) { 
    836         debugWarning("Could not set sync source connection.\n"); 
    837     } 
    838  
    839     result &= updateActiveSyncInfo(); 
    840     return result; 
     861        debugError("Could not set sync source connection while device reported it as possible.\n"); 
     862        retval = false; // proceed to rediscovery anyway 
     863    } 
     864 
     865    // we now have to rediscover the connections 
     866    if ( !rediscoverConnections() ) { 
     867        debugError( "Re-discovery of plug connections failed\n" ); 
     868        return false; 
     869    } 
     870    return retval; 
    841871} 
    842872 
     
    9851015    result &= serializeSyncInfoVector( basePath + "SyncInfo", ser, m_syncInfos ); 
    9861016 
    987     int i = 0; 
    988     for ( SyncInfoVector::const_iterator it = m_syncInfos.begin(); 
    989           it != m_syncInfos.end(); 
    990           ++it ) 
    991     { 
    992         const SyncInfo& info = *it; 
    993         if ( m_activeSyncInfo == &info ) { 
    994             result &= ser.write( basePath + "m_activeSyncInfo",  i ); 
    995             break; 
    996         } 
    997         i++; 
    998     } 
    999  
    10001017    return result; 
    10011018} 
     
    10421059    m_pPlugManager->deserializeUpdate( basePath, deser ); 
    10431060 
    1044     if ( deser.isExisting(basePath + "m_activeSyncInfo" ) ) { 
    1045         // the sync info doesn't have to be there. 
    1046  
    1047         unsigned int i; 
    1048         result &= deser.read( basePath + "m_activeSyncInfo", i ); 
    1049         if ( i < m_syncInfos.size() ) { 
    1050             m_activeSyncInfo = &m_syncInfos[i]; 
    1051             // but if it is we want it selected 
    1052             result &= setActiveSync(*m_activeSyncInfo); 
    1053         } 
    1054     } 
     1061    // this might have changed since the cache was saved 
     1062    // if the config ID doesn't account for the clock source 
     1063    if(!rediscoverConnections()) { 
     1064        debugError("Could not rediscover plug connections\n"); 
     1065    } 
     1066 
    10551067    return result; 
    10561068} 
  • trunk/libffado/src/libavc/general/avc_unit.h

    r1239 r1498  
    8888    virtual const SyncInfoVector& getSyncInfos() const 
    8989        { return m_syncInfos; } 
    90     virtual const SyncInfo* getActiveSyncInfo() const 
    91         { return m_activeSyncInfo; } 
     90    virtual const SyncInfo* getActiveSyncInfo(); 
    9291 
    9392    virtual bool setActiveSync( const SyncInfo& syncInfo ); 
     
    9897    SubunitAudio* getAudioSubunit( subunit_id_t subunitId ) 
    9998        { return dynamic_cast<SubunitAudio*>( 
    100                    getSubunit( AVC1394_SUBUNIT_AUDIO , subunitId ));}; 
     99                   getSubunit( eST_Audio , subunitId ));}; 
    101100    SubunitMusic* getMusicSubunit( subunit_id_t subunitId ) 
    102101        { return dynamic_cast<SubunitMusic*>( 
    103                    getSubunit( AVC1394_SUBUNIT_MUSIC , subunitId ));}; 
     102                   getSubunit( eST_Music , subunitId ));}; 
    104103    Subunit* getSubunit( subunit_type_t subunitType, 
    105104                         subunit_id_t subunitId ) const; 
     
    122121 
    123122    virtual bool enumerateSubUnits(); 
     123    virtual bool rediscoverConnections(); 
    124124    virtual bool discoverPlugConnections(); 
    125125    virtual bool discoverSubUnitsPlugConnections(); 
     
    131131    virtual bool propagatePlugInfo(); 
    132132    virtual bool discoverSyncModes(); 
    133     virtual bool updateActiveSyncInfo(); 
    134133    virtual bool checkSyncConnectionsAndAddToList( AVC::PlugVector& plhs, 
    135134                                           AVC::PlugVector& prhs, 
     
    167166    PlugManager*              m_pPlugManager; 
    168167    SyncInfoVector            m_syncInfos; 
    169     SyncInfo*                 m_activeSyncInfo; 
    170168 
    171169private: 
  • trunk/libffado/src/libavc/general/avc_unit_info.h

    r864 r1498  
    2727#include "avc_generic.h" 
    2828 
    29 #include <libavc1394/avc1394.h> 
     29#define AVC1394_CMD_UNIT_INFO 0x30 
    3030 
    3131namespace AVC { 
     
    3535{ 
    3636public: 
    37  
    38     enum EUnitType { 
    39         eUT_Monitor       = AVC1394_SUBUNIT_VIDEO_MONITOR, 
    40         eUT_Audio         = AVC1394_SUBUNIT_AUDIO, 
    41         eUT_Printer       = AVC1394_SUBUNIT_PRINTER, 
    42         eUT_Disc          = AVC1394_SUBUNIT_DISC_RECORDER, 
    43         eUT_VCR           = AVC1394_SUBUNIT_VCR, 
    44         eUT_Tuner         = AVC1394_SUBUNIT_TUNER, 
    45         eUT_CA            = AVC1394_SUBUNIT_CA, 
    46         eUT_Camera        = AVC1394_SUBUNIT_VIDEO_CAMERA, 
    47         eUT_Panel         = AVC1394_SUBUNIT_PANEL, 
    48         eUT_BulltinBoard  = AVC1394_SUBUNIT_BULLETIN_BOARD, 
    49         eUT_CameraStorage = AVC1394_SUBUNIT_CAMERA_STORAGE, 
    50         eUT_Music         = AVC1394_SUBUNIT_MUSIC, 
    51         eUT_VendorUnique  = AVC1394_SUBUNIT_VENDOR_UNIQUE, 
    52         eUT_Reserved      = AVC1394_SUBUNIT_RESERVED, 
    53         eUT_Extended      = AVC1394_SUBUNIT_EXTENDED, 
    54         eUT_Unit          = AVC1394_SUBUNIT_UNIT, 
    55     }; 
    56  
    5737    UnitInfoCmd( Ieee1394Service& ieee1349service ); 
    5838    virtual ~UnitInfoCmd(); 
  • trunk/libffado/src/libavc/general/avc_vendor_dependent_cmd.h

    r864 r1498  
    2727#include "avc_generic.h" 
    2828 
    29 #include <libavc1394/avc1394.h> 
    3029namespace AVC { 
    3130 
  • trunk/libffado/src/libavc/musicsubunit/avc_descriptor_music.h

    r1361 r1498  
    3737 
    3838#include "debugmodule/debugmodule.h" 
    39  
    40 #include <libavc1394/avc1394.h> 
    4139 
    4240#include <vector> 
  • trunk/libffado/src/libavc/streamformat/avc_extended_stream_format.h

    r1361 r1498  
    2828#include "../general/avc_extended_cmd_generic.h" 
    2929 
    30 #include <libavc1394/avc1394.h> 
    3130#include <iostream> 
    3231#include <vector> 
  • trunk/libffado/src/libcontrol/ClockSelect.cpp

    r1336 r1498  
    171171} 
    172172 
     173bool 
     174ClockSelect::canChangeValue() 
     175{ 
     176    return m_Device.getStreamingState() == FFADODevice::eSS_Idle; 
     177} 
     178 
    173179void 
    174180ClockSelect::show() 
     
    240246} 
    241247 
     248bool 
     249SamplerateSelect::canChangeValue() 
     250{ 
     251    return m_Device.getStreamingState() == FFADODevice::eSS_Idle; 
     252} 
     253 
    242254void 
    243255SamplerateSelect::show() 
     
    248260} 
    249261 
     262// --- stream status feedback selection --- 
     263 
     264StreamingStatus::StreamingStatus(FFADODevice &d) 
     265: Enum(&d) 
     266, m_Device( d ) 
     267{ 
     268    setName("StreamingStatus"); 
     269    setLabel("Streaming Status"); 
     270    setDescription("Obtain information of the current streaming status of a device"); 
     271} 
     272 
     273bool 
     274StreamingStatus::select(int idx) 
     275{ 
     276    debugWarning("Cannot change stream status through control interface\n"); 
     277    return false; 
     278} 
     279 
     280int 
     281StreamingStatus::selected() 
     282{ 
     283    return m_Device.getStreamingState(); 
     284} 
     285 
     286int 
     287StreamingStatus::count() 
     288{ 
     289    // NOTE: this should correspond to the number of enums in FFADODevice::eStreamingState 
     290    return 4; 
     291} 
     292 
     293std::string 
     294StreamingStatus::getEnumLabel(int idx) 
     295{ 
     296    switch(idx) { 
     297        case FFADODevice::eSS_Idle: 
     298            return "Idle"; 
     299        case FFADODevice::eSS_Sending: 
     300            return "Sending"; 
     301        case FFADODevice::eSS_Receiving: 
     302            return "Receiving"; 
     303        case FFADODevice::eSS_Both: 
     304            return "Both"; 
     305        default: 
     306            debugError("Invalid enum index specified: %d\n", idx); 
     307            return "Invalid enum index"; 
     308    } 
     309} 
     310 
     311bool 
     312StreamingStatus::canChangeValue() 
     313{ 
     314    return false; 
     315} 
     316 
     317void 
     318StreamingStatus::show() 
     319{ 
     320    debugOutput( DEBUG_LEVEL_NORMAL, "StreamingStatus Element %s, current: %d\n", 
     321        getName().c_str(), m_Device.getStreamingState()); 
     322} 
     323 
    250324 
    251325} // namespace Control 
  • trunk/libffado/src/libcontrol/ClockSelect.h

    r1336 r1498  
    5858    virtual std::string getAttributeName(int attridx); 
    5959 
     60    virtual bool canChangeValue(); 
     61 
    6062    virtual void show(); 
    6163 
     
    8082    virtual std::string getEnumLabel(int idx); 
    8183 
     84    virtual bool canChangeValue(); 
     85 
     86    virtual void show(); 
     87 
     88protected: 
     89    FFADODevice &m_Device; 
     90}; 
     91 
     92/*! 
     93 * @brief Stream status control element 
     94 */ 
     95class StreamingStatus 
     96: public Enum 
     97{ 
     98public: 
     99    StreamingStatus(FFADODevice &); 
     100    virtual ~StreamingStatus() {}; 
     101 
     102    virtual bool select(int idx); 
     103    virtual int selected(); 
     104    virtual int count(); 
     105    virtual std::string getEnumLabel(int idx); 
     106 
     107    virtual bool canChangeValue(); 
     108 
    82109    virtual void show(); 
    83110 
  • trunk/libffado/src/libcontrol/Element.cpp

    r1336 r1498  
    9292} 
    9393 
     94bool 
     95Element::isControlLocked() 
     96{ 
     97    return getLock().isLocked(); 
     98} 
     99 
    94100Util::Mutex& 
    95101Element::getLock() 
     
    101107        return *m_element_lock; 
    102108    } 
     109} 
     110 
     111bool 
     112Element::canChangeValue() 
     113{ 
     114    return true; 
    103115} 
    104116 
  • trunk/libffado/src/libcontrol/Element.h

    r1336 r1498  
    8383        {return m_id;}; 
    8484 
     85    // can the value of this element change? 
     86    virtual bool canChangeValue(); 
     87 
    8588    // these allow to prevent external access to the control elements 
    8689    // e.g. when the config tree is rebuilt 
    8790    virtual void lockControl(); 
    8891    virtual void unlockControl(); 
     92    virtual bool isControlLocked(); 
    8993 
    9094    /** 
  • trunk/libffado/src/libcontrol/Nickname.cpp

    r1158 r1498  
    5353} 
    5454 
     55bool 
     56Nickname::canChangeValue() 
     57{ 
     58    return m_Device.canChangeNickname(); 
     59} 
    5560 
    5661void 
  • trunk/libffado/src/libcontrol/Nickname.h

    r1063 r1498  
    4949    virtual std::string getValue(); 
    5050 
     51    virtual bool canChangeValue(); 
     52 
    5153    virtual void show(); 
    5254 
  • trunk/libffado/src/libieee1394/CycleTimerHelper.cpp

    r1348 r1498  
    357357    uint64_t local_time; 
    358358    int64_t usecs_late; 
    359     int ntries=4
     359    int ntries=10
    360360    uint64_t cycle_timer_ticks; 
    361     double diff_ticks; 
    362  
    363     // if the difference between the predicted value and the 
     361    int64_t err_ticks; 
     362    bool not_good; 
     363 
     364    // if the difference between the predicted value at readout time and the 
    364365    // actual value seems to be too large, retry reading the cycle timer 
    365366    // some host controllers return bogus values on some reads 
     
    373374        usecs_late = local_time - m_sleep_until; 
    374375        cycle_timer_ticks = CYCLE_TIMER_TO_TICKS(cycle_timer); 
    375         diff_ticks = diffTicks(cycle_timer_ticks, (int64_t)m_next_time_ticks); 
     376 
     377        // calculate the CTR_TICKS we expect to read at "local_time" 
     378        // then calculate the difference with what we actually read, 
     379        // taking wraparound into account. If these deviate too much 
     380        // from eachother then read the register again (bogus read). 
     381        int64_t expected_ticks = getCycleTimerTicks(local_time); 
     382        err_ticks = diffTicks(cycle_timer_ticks, expected_ticks); 
    376383 
    377384        // check for unrealistic CTR reads (NEC controller does that sometimes) 
    378         if(diff_ticks < -((double)TICKS_PER_HALFCYCLE)) { 
    379             debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE,  
    380                         "(%p) have to retry CTR read, diff unrealistic: diff: %f, max: %f (try: %d)\n",  
    381                         this, diff_ticks, -((double)TICKS_PER_HALFCYCLE), ntries); 
    382         } 
    383  
    384     } while( diff_ticks < -((double)TICKS_PER_HALFCYCLE)  
    385              && --ntries && !m_first_run && !m_unhandled_busreset); 
     385        not_good = (-err_ticks > 1*TICKS_PER_HALFCYCLE || err_ticks > 1*TICKS_PER_HALFCYCLE); 
     386        if(not_good) { 
     387            debugOutput(DEBUG_LEVEL_VERBOSE,  
     388                        "(%p) have to retry CTR read, diff unrealistic: diff: %lld, max: +/- %ld (try: %d) %lld\n",  
     389                        this, err_ticks, 1*TICKS_PER_CYCLE, ntries, expected_ticks); 
     390            // sleep half a cycle to make sure the hardware moved on 
     391            Util::SystemTimeSource::SleepUsecRelative(USECS_PER_CYCLE/2); 
     392        } 
     393 
     394    } while(not_good && --ntries && !m_first_run && !m_unhandled_busreset); 
    386395 
    387396    // grab the lock after sleeping, otherwise we can't be interrupted by 
     
    390399    // wakeup and read is as small as possible 
    391400    Util::MutexLockHelper lock(*m_update_lock); 
     401 
     402    // the difference between the measured and the expected time 
     403    int64_t diff_ticks = diffTicks(cycle_timer_ticks, (int64_t)m_next_time_ticks); 
    392404 
    393405    // // simulate a random scheduling delay between (0-10ms) 
     
    418430        } 
    419431        m_first_run = false; 
    420     } else if (diff_ticks > 20.0*m_ticks_per_update) { 
     432    } else if (diff_ticks > m_ticks_per_update * 20) { 
    421433        debugOutput(DEBUG_LEVEL_VERBOSE, 
    422                     "re-init dll due to too large tick diff: %f >> %f\n", 
    423                     diff_ticks, (float)(20.0*m_ticks_per_update)); 
     434                    "re-init dll due to too large tick diff: %lld >> %f\n", 
     435                    diff_ticks, (float)(m_ticks_per_update * 20)); 
    424436        if(!initDLL()) { 
    425437            debugError("(%p) Could not init DLL\n", this); 
     
    442454        // the corrected difference between predicted and actual ctr 
    443455        // i.e. DLL error signal 
    444         double diff_ticks_corr; 
     456        int64_t diff_ticks_corr; 
    445457        if (ticks_late > 0) { 
    446458            diff_ticks_corr = diff_ticks - ticks_late; 
    447459            debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE, 
    448                                "diff_ticks_corr=%f, diff_ticks = %f, ticks_late = %lld\n", 
     460                               "diff_ticks_corr=%lld, diff_ticks = %lld, ticks_late = %lld\n", 
    449461                               diff_ticks_corr, diff_ticks, ticks_late); 
    450462        } else { 
     
    487499        // and coeff_b < 1, hence tmp is not near wrapping 
    488500 
    489         double step_ticks = (coeff_b * diff_ticks_corr); 
     501        double diff_ticks_corr_d =  (double)diff_ticks_corr; 
     502        double step_ticks = (coeff_b * diff_ticks_corr_d); 
    490503        debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 
    491504                           "diff_ticks_corr=%f, step_ticks=%f\n", 
    492                            diff_ticks_corr, step_ticks); 
     505                           diff_ticks_corr_d, step_ticks); 
    493506 
    494507        // the same goes for m_dll_e2, which should be approx equal 
     
    515528 
    516529        // update the DLL state 
    517         m_dll_e2 += coeff_c * diff_ticks_corr
     530        m_dll_e2 += coeff_c * diff_ticks_corr_d
    518531 
    519532        // update the y-axis values 
     
    525538                           m_current_time_usecs, m_next_time_usecs, usecs_late, ticks_late); 
    526539        debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 
    527                            " ticks: current: %f next: %f diff=%f\n", 
     540                           " ticks: current: %f next: %f diff=%lld\n", 
    528541                           m_current_time_ticks, m_next_time_ticks, diff_ticks); 
    529542        debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 
  • trunk/libffado/src/libieee1394/ieee1394service.cpp

    r1441 r1498  
    3131#include "CycleTimerHelper.h" 
    3232 
    33 #include <libavc1394/avc1394.h> 
    3433#include <libraw1394/csr.h> 
    3534#include <libiec61883/iec61883.h> 
     
    3837#include "libutil/Watchdog.h" 
    3938#include "libutil/PosixMutex.h" 
     39#include "libutil/Configuration.h" 
    4040 
    4141#include <errno.h> 
     
    5252 
    5353Ieee1394Service::Ieee1394Service() 
    54     : m_handle( 0 ) 
     54    : m_configuration( NULL ) 
     55    , m_handle( 0 ) 
    5556    , m_handle_lock( new Util::PosixMutex("SRCVHND") ) 
    5657    , m_resetHandle( 0 ) 
     
    6465    , m_pCTRHelper ( new CycleTimerHelper( *this, IEEE1394SERVICE_CYCLETIMER_DLL_UPDATE_INTERVAL_USEC ) ) 
    6566    , m_have_new_ctr_read ( false ) 
     67    , m_filterFCPResponse ( false ) 
    6668    , m_pWatchdog ( new Util::Watchdog() ) 
    6769{ 
     
    7880 
    7981Ieee1394Service::Ieee1394Service(bool rt, int prio) 
    80     : m_handle( 0 ) 
     82    : m_configuration( NULL ) 
     83    , m_handle( 0 ) 
    8184    , m_handle_lock( new Util::PosixMutex("SRCVHND") ) 
    8285    , m_resetHandle( 0 ) 
     
    9093    , m_pCTRHelper ( new CycleTimerHelper( *this, IEEE1394SERVICE_CYCLETIMER_DLL_UPDATE_INTERVAL_USEC, 
    9194                                           rt && IEEE1394SERVICE_CYCLETIMER_HELPER_RUN_REALTIME, 
    92                                            prio + IEEE1394SERVICE_CYCLETIMER_HELPER_PRIO_INCREASE ) ) 
     95                                           IEEE1394SERVICE_CYCLETIMER_HELPER_PRIO ) ) 
    9396    , m_have_new_ctr_read ( false ) 
     97    , m_filterFCPResponse ( false ) 
    9498    , m_pWatchdog ( new Util::Watchdog() ) 
    9599{ 
     
    137141} 
    138142 
     143bool 
     144Ieee1394Service::useConfiguration(Util::Configuration *c) 
     145{ 
     146    m_configuration = c; 
     147    return configurationUpdated(); 
     148} 
     149 
     150bool 
     151Ieee1394Service::configurationUpdated() 
     152{ 
     153    if(m_configuration) { 
     154         
     155    } 
     156    return true; 
     157} 
     158 
    139159#define DEVICEFAILTEXT "Could not get libraw1394 handle.\n\ 
    140160This usually means:\n\ 
     
    190210        Util::SystemTimeSource::SleepUsecRelative( sleep_time_ms * 1000); 
    191211    } while (gen_current != getGeneration() && --nb_tries); 
     212 
     213    debugOutput(DEBUG_LEVEL_VERBOSE, "Bus reset storm over at gen: %u\n", gen_current); 
    192214 
    193215    if (!nb_tries) { 
     
    278300    raw1394handle_t tmp_handle = raw1394_new_handle(); 
    279301    if ( tmp_handle == NULL ) { 
    280         debugError("Could not get temporaty libraw1394 handle.\n"); 
     302        debugError("Could not get temporary libraw1394 handle.\n"); 
    281303        return false; 
    282304    } 
     
    299321    } 
    300322 
     323    // set userdata 
    301324    raw1394_set_userdata( m_handle, this ); 
    302325    raw1394_set_userdata( m_resetHandle, this ); 
     
    308331                                   this->armHandlerLowLevel ); 
    309332 
     333    int split_timeout = IEEE1394SERVICE_MIN_SPLIT_TIMEOUT_USECS; 
     334    if(m_configuration) { 
     335        m_configuration->getValueForSetting("ieee1394.min_split_timeout_usecs", split_timeout); 
     336    } 
     337 
     338    // set SPLIT_TIMEOUT to one second to cope with DM1x00 devices that 
     339    // send responses regardless of the timeout 
     340    int timeout = getSplitTimeoutUsecs(getLocalNodeId()); 
     341    debugOutput(DEBUG_LEVEL_VERBOSE, "Minimum SPLIT_TIMEOUT: %d. Current: %d\n", split_timeout, timeout); 
     342    if (timeout < split_timeout) { 
     343        if(!setSplitTimeoutUsecs(getLocalNodeId(), split_timeout+124)) { 
     344            debugWarning("Could not set SPLIT_TIMEOUT to min requested (%d)\n", split_timeout); 
     345        } 
     346        timeout = getSplitTimeoutUsecs(getLocalNodeId()); 
     347        if (timeout < split_timeout) { 
     348            debugWarning("Set SPLIT_TIMEOUT to min requested (%d) did not succeed\n", split_timeout); 
     349        } 
     350    } 
     351 
     352    // init helpers 
    310353    if(!m_pCTRHelper) { 
    311354        debugFatal("No CycleTimerHelper available, bad!\n"); 
     
    323366    } 
    324367    m_pIsoManager->setVerboseLevel(getDebugLevel()); 
     368 
    325369    if(!m_pIsoManager->init()) { 
    326370        debugFatal("Could not initialize IsoHandlerManager\n"); 
     
    342386    bool result = true; 
    343387    if (priority > THREAD_MAX_RTPRIO) priority = THREAD_MAX_RTPRIO; 
     388    if (priority < THREAD_MIN_RTPRIO) priority = THREAD_MIN_RTPRIO; 
    344389    m_base_priority = priority; 
    345390    m_realtime = rt; 
     
    352397        debugOutput(DEBUG_LEVEL_VERBOSE, "Switching CycleTimerHelper to (rt=%d, prio=%d)\n",  
    353398                                         rt && IEEE1394SERVICE_CYCLETIMER_HELPER_RUN_REALTIME, 
    354                                          priority + IEEE1394SERVICE_CYCLETIMER_HELPER_PRIO_INCREASE); 
     399                                         IEEE1394SERVICE_CYCLETIMER_HELPER_PRIO); 
    355400        result &= m_pCTRHelper->setThreadParameters(rt && IEEE1394SERVICE_CYCLETIMER_HELPER_RUN_REALTIME, 
    356                                                     priority + IEEE1394SERVICE_CYCLETIMER_HELPER_PRIO_INCREASE); 
     401                                                    IEEE1394SERVICE_CYCLETIMER_HELPER_PRIO); 
    357402    } 
    358403    return result; 
     
    463508{ 
    464509    Util::MutexLockHelper lock(*m_handle_lock); 
     510    return readNoLock(nodeId, addr, length, buffer); 
     511} 
     512 
     513bool 
     514Ieee1394Service::readNoLock( fb_nodeid_t nodeId, 
     515                             fb_nodeaddr_t addr, 
     516                             size_t length, 
     517                             fb_quadlet_t* buffer ) 
     518{ 
    465519    if (nodeId == INVALID_NODE_ID) { 
    466520        debugWarning("operation on invalid node\n"); 
     
    511565{ 
    512566    Util::MutexLockHelper lock(*m_handle_lock); 
     567    return writeNoLock(nodeId, addr, length, data); 
     568} 
     569 
     570bool 
     571Ieee1394Service::writeNoLock( fb_nodeid_t nodeId, 
     572                              fb_nodeaddr_t addr, 
     573                              size_t length, 
     574                              fb_quadlet_t* data ) 
     575{ 
    513576    if (nodeId == INVALID_NODE_ID) { 
    514577        debugWarning("operation on invalid node\n"); 
     
    601664                                   unsigned int* resp_len ) 
    602665{ 
     666    // FIXME: simplify semantics 
    603667    if (nodeId == INVALID_NODE_ID) { 
    604668        debugWarning("operation on invalid node\n"); 
    605669        return false; 
    606670    } 
    607     // FIXME: this requires transactionBlockClose to unlock 
     671    // NOTE: this expects a call to transactionBlockClose to unlock 
    608672    m_handle_lock->Lock(); 
    609     for (int i = 0; i < len; ++i) { 
    610         buf[i] = CondSwapFromBus32( buf[i] ); 
    611     } 
    612  
    613     fb_quadlet_t* result = 
    614         avc1394_transaction_block2( m_handle, 
    615                                     nodeId, 
    616                                     buf, 
    617                                     len, 
    618                                     resp_len, 
    619                                     10 ); 
    620  
    621     for ( unsigned int i = 0; i < *resp_len; ++i ) { 
    622         result[i] = CondSwapToBus32( result[i] ); 
    623     } 
    624  
    625     return result; 
    626 
    627  
     673 
     674    // clear the request & response memory 
     675    memset(&m_fcp_block, 0, sizeof(m_fcp_block)); 
     676 
     677    // make a local copy of the request 
     678    if(len < MAX_FCP_BLOCK_SIZE_QUADS) { 
     679        memcpy(m_fcp_block.request, buf, len*sizeof(quadlet_t)); 
     680        m_fcp_block.request_length = len; 
     681    } else { 
     682        debugWarning("Truncating FCP request\n"); 
     683        memcpy(m_fcp_block.request, buf, MAX_FCP_BLOCK_SIZE_BYTES); 
     684        m_fcp_block.request_length = MAX_FCP_BLOCK_SIZE_QUADS; 
     685    } 
     686    m_fcp_block.target_nodeid = 0xffc0 | nodeId; 
     687 
     688    bool success = doFcpTransaction(); 
     689    if(success) { 
     690        *resp_len = m_fcp_block.response_length; 
     691        return m_fcp_block.response; 
     692    } else { 
     693        debugWarning("FCP transaction failed\n"); 
     694        *resp_len = 0; 
     695        return NULL; 
     696    } 
     697
    628698 
    629699bool 
    630700Ieee1394Service::transactionBlockClose() 
    631701{ 
    632     avc1394_transaction_block_close( m_handle ); 
    633702    m_handle_lock->Unlock(); 
    634703    return true; 
     704} 
     705 
     706// FCP code 
     707bool 
     708Ieee1394Service::doFcpTransaction() 
     709{ 
     710    for(int i=0; i < IEEE1394SERVICE_FCP_MAX_TRIES; i++) { 
     711        if(doFcpTransactionTry()) { 
     712            return true; 
     713        } else { 
     714            debugOutput(DEBUG_LEVEL_VERBOSE, "FCP transaction try %d failed\n", i); 
     715            Util::SystemTimeSource::SleepUsecRelative( IEEE1394SERVICE_FCP_SLEEP_BETWEEN_FAILURES_USECS); 
     716        } 
     717    } 
     718    debugError("FCP transaction didn't succeed in %d tries\n", IEEE1394SERVICE_FCP_MAX_TRIES); 
     719    return false; 
     720} 
     721 
     722#define FCP_COMMAND_ADDR   0xFFFFF0000B00ULL 
     723#define FCP_RESPONSE_ADDR  0xFFFFF0000D00ULL 
     724 
     725/* AV/C FCP response codes */ 
     726#define FCP_RESPONSE_NOT_IMPLEMENTED 0x08000000 
     727#define FCP_RESPONSE_ACCEPTED 0x09000000 
     728#define FCP_RESPONSE_REJECTED 0x0A000000 
     729#define FCP_RESPONSE_IN_TRANSITION 0x0B000000 
     730#define FCP_RESPONSE_IMPLEMENTED 0x0C000000 
     731#define FCP_RESPONSE_STABLE 0x0C000000 
     732#define FCP_RESPONSE_CHANGED 0x0D000000 
     733#define FCP_RESPONSE_INTERIM 0x0F000000 
     734 
     735/* AV/C FCP mask macros */ 
     736#define FCP_MASK_START(x) ((x) & 0xF0000000) 
     737#define FCP_MASK_CTYPE(x) ((x) & 0x0F000000) 
     738#define FCP_MASK_RESPONSE(x) ((x) & 0x0F000000) 
     739#define FCP_MASK_SUBUNIT(x) ((x) & 0x00FF0000) 
     740#define FCP_MASK_SUBUNIT_TYPE(x) ((x) & 0x00F80000) 
     741#define FCP_MASK_SUBUNIT_ID(x) ((x) & 0x00070000) 
     742#define FCP_MASK_OPCODE(x) ((x) & 0x0000FF00) 
     743#define FCP_MASK_SUBUNIT_AND_OPCODE(x) ((x) & 0x00FFFF00) 
     744#define FCP_MASK_OPERAND0(x) ((x) & 0x000000FF) 
     745#define FCP_MASK_OPERAND(x, n) ((x) & (0xFF000000 >> ((((n)-1)%4)*8))) 
     746#define FCP_MASK_RESPONSE_OPERAND(x, n) ((x) & (0xFF000000 >> (((n)%4)*8))) 
     747 
     748bool 
     749Ieee1394Service::doFcpTransactionTry() 
     750{ 
     751    // NOTE that access to this is protected by the m_handle lock 
     752    int err; 
     753    bool retval = true; 
     754    uint64_t timeout; 
     755 
     756    // prepare an fcp response handler 
     757    raw1394_set_fcp_handler(m_handle, _avc_fcp_handler); 
     758 
     759    // start listening for FCP requests 
     760    // this fails if some other program is listening for a FCP response 
     761    err = raw1394_start_fcp_listen(m_handle); 
     762    if(err) { 
     763        debugOutput(DEBUG_LEVEL_VERBOSE, "could not start FCP listen (err=%d, errno=%d)\n", err, errno); 
     764        retval = false; 
     765        goto out; 
     766    } 
     767 
     768    m_fcp_block.status = eFS_Waiting; 
     769 
     770    #ifdef DEBUG 
     771    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"fcp request: node 0x%hX, length = %d bytes\n", 
     772                m_fcp_block.target_nodeid, m_fcp_block.request_length*4); 
     773    printBuffer(DEBUG_LEVEL_VERY_VERBOSE, m_fcp_block.request_length, m_fcp_block.request ); 
     774    #endif 
     775 
     776    // write the FCP request 
     777    if(!writeNoLock( m_fcp_block.target_nodeid, FCP_COMMAND_ADDR, 
     778                     m_fcp_block.request_length, m_fcp_block.request)) { 
     779        debugOutput(DEBUG_LEVEL_VERBOSE, "write of FCP request failed\n"); 
     780        retval = false; 
     781        goto out; 
     782    } 
     783 
     784    // wait for the response to arrive 
     785    struct pollfd raw1394_poll; 
     786    raw1394_poll.fd = raw1394_get_fd(m_handle); 
     787    raw1394_poll.events = POLLIN; 
     788 
     789    timeout = Util::SystemTimeSource::getCurrentTimeAsUsecs() + 
     790              IEEE1394SERVICE_FCP_RESPONSE_TIMEOUT_USEC; 
     791 
     792    while(m_fcp_block.status == eFS_Waiting  
     793          && Util::SystemTimeSource::getCurrentTimeAsUsecs() < timeout) { 
     794        if(poll( &raw1394_poll, 1, IEEE1394SERVICE_FCP_POLL_TIMEOUT_MSEC) > 0) { 
     795            if (raw1394_poll.revents & POLLIN) { 
     796                raw1394_loop_iterate(m_handle); 
     797            } 
     798        } 
     799    } 
     800 
     801    // stop listening for FCP responses 
     802    err = raw1394_stop_fcp_listen(m_handle); 
     803    if(err) { 
     804        debugOutput(DEBUG_LEVEL_VERBOSE, "could not stop FCP listen (err=%d, errno=%d)\n", err, errno); 
     805        retval = false; 
     806        goto out; 
     807    } 
     808 
     809    // check the request and figure out what happened 
     810    if(m_fcp_block.status == eFS_Waiting) { 
     811        debugOutput(DEBUG_LEVEL_VERBOSE, "FCP response timed out\n"); 
     812        retval = false; 
     813        goto out; 
     814    } 
     815    if(m_fcp_block.status == eFS_Error) { 
     816        debugError("FCP request/response error\n"); 
     817        retval = false; 
     818        goto out; 
     819    } 
     820 
     821out: 
     822    m_fcp_block.status = eFS_Empty; 
     823    return retval; 
     824} 
     825 
     826int 
     827Ieee1394Service::_avc_fcp_handler(raw1394handle_t handle, nodeid_t nodeid,  
     828                                  int response, size_t length, 
     829                                  unsigned char *data) 
     830{ 
     831    Ieee1394Service *service = static_cast<Ieee1394Service *>(raw1394_get_userdata(handle)); 
     832    if(service) { 
     833        return service->handleFcpResponse(nodeid, response, length, data); 
     834    } else return -1; 
     835} 
     836 
     837int 
     838Ieee1394Service::handleFcpResponse(nodeid_t nodeid, 
     839                                   int response, size_t length, 
     840                                   unsigned char *data) 
     841{ 
     842    static struct sFcpBlock fcp_block_last; 
     843 
     844    fb_quadlet_t *data_quads = (fb_quadlet_t *)data; 
     845    #ifdef DEBUG 
     846    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"fcp response: node 0x%hX, response = %d, length = %d bytes\n", 
     847                nodeid, response, length); 
     848    printBuffer(DEBUG_LEVEL_VERY_VERBOSE, (length+3)/4, data_quads ); 
     849    #endif 
     850 
     851    if (response && length > 3) { 
     852        if(length > MAX_FCP_BLOCK_SIZE_BYTES) { 
     853            length = MAX_FCP_BLOCK_SIZE_BYTES; 
     854            debugWarning("Truncated FCP response\n"); 
     855        } 
     856 
     857        // is it an actual response or is it INTERIM? 
     858        quadlet_t first_quadlet = CondSwapFromBus32(data_quads[0]); 
     859        if(FCP_MASK_RESPONSE(first_quadlet) == FCP_RESPONSE_INTERIM) { 
     860            debugOutput(DEBUG_LEVEL_VERBOSE, "INTERIM\n"); 
     861        } else { 
     862            // it's an actual response, check if it matches our request 
     863            if(nodeid != m_fcp_block.target_nodeid) { 
     864                debugOutput(DEBUG_LEVEL_VERBOSE, "FCP response node id's don't match! (%x, %x)\n", 
     865                                                 m_fcp_block.target_nodeid, nodeid); 
     866            } else if (first_quadlet == 0) { 
     867                debugWarning("Bogus FCP response\n"); 
     868                printBuffer(DEBUG_LEVEL_WARNING, (length+3)/4, data_quads ); 
     869#ifdef DEBUG 
     870            } else if(FCP_MASK_RESPONSE(first_quadlet) < 0x08000000) { 
     871                debugWarning("Bogus AV/C FCP response code\n"); 
     872                printBuffer(DEBUG_LEVEL_WARNING, (length+3)/4, data_quads ); 
     873#endif 
     874            } else if(FCP_MASK_SUBUNIT_AND_OPCODE(first_quadlet)  
     875                      != FCP_MASK_SUBUNIT_AND_OPCODE(CondSwapFromBus32(m_fcp_block.request[0]))) { 
     876                debugOutput(DEBUG_LEVEL_VERBOSE, "FCP response not for this request: %08lX != %08lX\n", 
     877                             FCP_MASK_SUBUNIT_AND_OPCODE(first_quadlet), 
     878                             FCP_MASK_SUBUNIT_AND_OPCODE(CondSwapFromBus32(m_fcp_block.request[0]))); 
     879            } else if(m_filterFCPResponse && (memcmp(fcp_block_last.response, data, length) == 0)) { 
     880                // This is workaround for the Edirol FA-101. The device tends to send more than 
     881                // one responde to one request. This seems to happen when discovering  
     882                // function blocks and looks very likely there is a race condition in the  
     883                // device. The workaround here compares the just arrived FCP responde 
     884                // to the last one. If it is the same as the previously one then we 
     885                // just ignore it. The downside of this approach is, we cannot issue 
     886                // the same FCP twice. 
     887                debugWarning("Received duplicate FCP response. Ignore it\n"); 
     888            } else { 
     889                m_fcp_block.response_length = (length + sizeof(quadlet_t) - 1) / sizeof(quadlet_t); 
     890                memcpy(m_fcp_block.response, data, length); 
     891                if (m_filterFCPResponse) { 
     892                    memcpy(fcp_block_last.response, data, length); 
     893                } 
     894                m_fcp_block.status = eFS_Responded; 
     895            } 
     896       } 
     897    } 
     898    return 0; 
     899} 
     900 
     901bool 
     902Ieee1394Service::setSplitTimeoutUsecs(fb_nodeid_t nodeId, unsigned int timeout) 
     903{ 
     904    Util::MutexLockHelper lock(*m_handle_lock); 
     905    debugOutput(DEBUG_LEVEL_VERBOSE, "setting SPLIT_TIMEOUT on node 0x%X to %uusecs...\n", nodeId, timeout); 
     906    unsigned int secs = timeout / 1000000; 
     907    unsigned int usecs = timeout % 1000000; 
     908 
     909    quadlet_t split_timeout_hi = CondSwapToBus32(secs & 7); 
     910    quadlet_t split_timeout_low = CondSwapToBus32(((usecs / 125) & 0x1FFF) << 19); 
     911 
     912    // write the CSR registers 
     913    if(!writeNoLock( 0xffc0 | nodeId, CSR_REGISTER_BASE + CSR_SPLIT_TIMEOUT_HI, 1, 
     914                  &split_timeout_hi)) { 
     915        debugOutput(DEBUG_LEVEL_VERBOSE, "write of CSR_SPLIT_TIMEOUT_HI failed\n"); 
     916        return false; 
     917    } 
     918    if(!writeNoLock( 0xffc0 | nodeId, CSR_REGISTER_BASE + CSR_SPLIT_TIMEOUT_LO, 1, 
     919                  &split_timeout_low)) { 
     920        debugOutput(DEBUG_LEVEL_VERBOSE, "write of CSR_SPLIT_TIMEOUT_LO failed\n"); 
     921        return false; 
     922    } 
     923    return true; 
     924} 
     925 
     926int 
     927Ieee1394Service::getSplitTimeoutUsecs(fb_nodeid_t nodeId) 
     928{ 
     929    Util::MutexLockHelper lock(*m_handle_lock); 
     930    quadlet_t split_timeout_hi; 
     931    quadlet_t split_timeout_low; 
     932 
     933    debugOutput(DEBUG_LEVEL_VERBOSE, "reading SPLIT_TIMEOUT on node 0x%X...\n", nodeId); 
     934 
     935    if(!readNoLock( 0xffc0 | nodeId, CSR_REGISTER_BASE + CSR_SPLIT_TIMEOUT_HI, 1, 
     936                  &split_timeout_hi)) { 
     937        debugOutput(DEBUG_LEVEL_VERBOSE, "read of CSR_SPLIT_TIMEOUT_HI failed\n"); 
     938        return 0; 
     939    } 
     940    debugOutput(DEBUG_LEVEL_VERBOSE, " READ HI: 0x%08lX\n", split_timeout_hi); 
     941 
     942    if(!readNoLock( 0xffc0 | nodeId, CSR_REGISTER_BASE + CSR_SPLIT_TIMEOUT_LO, 1, 
     943                  &split_timeout_low)) { 
     944        debugOutput(DEBUG_LEVEL_VERBOSE, "read of CSR_SPLIT_TIMEOUT_LO failed\n"); 
     945        return 0; 
     946    } 
     947    debugOutput(DEBUG_LEVEL_VERBOSE, " READ LO: 0x%08lX\n", split_timeout_low); 
     948 
     949    split_timeout_hi = CondSwapFromBus32(split_timeout_hi); 
     950    split_timeout_low = CondSwapFromBus32(split_timeout_low); 
     951 
     952    return (split_timeout_hi & 7) * 1000000 + (split_timeout_low >> 19) * 125; 
     953} 
     954 
     955void  
     956Ieee1394Service::setFCPResponseFiltering(bool enable) 
     957{ 
     958    m_filterFCPResponse = enable; 
    635959} 
    636960 
  • trunk/libffado/src/libieee1394/ieee1394service.h

    r1348 r1498  
    4141 
    4242class ARMHandler; 
     43 
     44#define MAX_FCP_BLOCK_SIZE_BYTES (512) 
     45#define MAX_FCP_BLOCK_SIZE_QUADS (MAX_FCP_BLOCK_SIZE_BYTES / 4) 
     46 
    4347class IsoHandlerManager; 
    4448class CycleTimerHelper; 
     
    4650namespace Util { 
    4751    class Watchdog; 
     52    class Configuration; 
    4853} 
    4954 
     
    227232     * @return true if succesful, false otherwise 
    228233     */ 
    229     bool lockCompareSwap64(  fb_nodeid_t nodeId, 
    230                         fb_nodeaddr_t addr, 
    231                         fb_octlet_t  compare_value, 
    232                         fb_octlet_t  swap_value, 
    233                         fb_octlet_t* result ); 
    234  
     234    bool lockCompareSwap64( fb_nodeid_t nodeId, 
     235                            fb_nodeaddr_t addr, 
     236                            fb_octlet_t  compare_value, 
     237                            fb_octlet_t  swap_value, 
     238                            fb_octlet_t* result ); 
     239 
     240    /** 
     241     * initiate AV/C transaction 
     242     * @param nodeId  
     243     * @param buf  
     244     * @param len  
     245     * @param resp_len  
     246     * @return  
     247     */ 
    235248    fb_quadlet_t* transactionBlock( fb_nodeid_t nodeId, 
    236249                                    fb_quadlet_t* buf, 
    237250                                    int len, 
    238                     unsigned int* resp_len ); 
    239  
     251                                    unsigned int* resp_len ); 
     252 
     253    /** 
     254     * close AV/C transaction. 
     255     * @param nodeId  
     256     * @param buf  
     257     * @param len  
     258     * @param resp_len  
     259     * @return  
     260     */ 
    240261    bool transactionBlockClose(); 
    241262 
     
    247268    void doBusReset(); 
    248269    bool waitForBusResetStormToEnd( int nb_tries, int sleep_time_ms ); 
     270 
     271    /** 
     272     * @brief register an AddressRangeMapping Handler 
     273     * @param h pointer to the handler to register 
     274     * 
     275     * @return true on success or false on failure 
     276     **/ 
     277 
     278    bool registerARMHandler( ARMHandler *h ); 
     279 
     280    /** 
     281     * @brief unregister ARM range 
     282     * @param h pointer to the handler to unregister 
     283     * @return true if successful, false otherwise 
     284     */ 
     285    bool unregisterARMHandler( ARMHandler *h ); 
     286 
     287    nodeaddr_t findFreeARMBlock( nodeaddr_t start, size_t length, size_t step ); 
    249288 
    250289    /** 
     
    259298 
    260299    /** 
    261      * @brief register an AddressRangeMapping Handler 
    262      * @param h pointer to the handler to register 
    263      * 
    264      * @return true on success or false on failure 
     300     * @brief update the current generation 
     301     * 
     302     * @return the current generation 
    265303     **/ 
    266  
    267     bool registerARMHandler( ARMHandler *h ); 
    268  
    269     /** 
    270      * @brief unregister ARM range 
    271      * @param h pointer to the handler to unregister 
    272      * @return true if successful, false otherwise 
    273      */ 
    274     bool unregisterARMHandler( ARMHandler *h ); 
    275  
    276     nodeaddr_t findFreeARMBlock( nodeaddr_t start, size_t length, size_t step ); 
     304    void updateGeneration() { 
     305        Util::MutexLockHelper lock(*m_handle_lock); 
     306        raw1394_update_generation( m_handle, getGeneration()); 
     307    } 
     308 
     309    /** 
     310     * @brief sets the SPLIT_TIMEOUT_HI and SPLIT_TIMEOUT_LO CSR registers 
     311     * 
     312     * sets the SPLIT_TIMEOUT_HI and SPLIT_TIMEOUT_LO CSR registers on node 
     313     * nodeId such that the timeout is equal to timeout 
     314     * 
     315     * @param nodeId node to set CSR registers on 
     316     * @param timeout timeout in usecs 
     317     * @return true if successful 
     318     */ 
     319    bool setSplitTimeoutUsecs(fb_nodeid_t nodeId, unsigned int timeout); 
     320 
     321    /** 
     322     * @brief gets the SPLIT_TIMEOUT_X timeout value 
     323     * 
     324     * gets the SPLIT_TIMEOUT_HI and SPLIT_TIMEOUT_LO CSR registers on node 
     325     * nodeId and recombine them into one usec value 
     326     * 
     327     * @param nodeId node to get CSR registers from 
     328     * @return timeout in usecs if successful, 0 else 
     329     */ 
     330    int getSplitTimeoutUsecs(fb_nodeid_t nodeId); 
     331 
     332    /** 
     333     * @brief use the provided configuration for this service 
     334     * 
     335     * only update the config once, before init. not thread safe, 
     336     * and no effect when things are already running. 
     337     * 
     338     * @param c configuration to use 
     339     * @return bool if this config is ok. 
     340     */ 
     341    bool useConfiguration(Util::Configuration *c); 
     342 
     343    Util::Configuration *getConfiguration() {return m_configuration;}; 
     344 
     345    /** 
     346     * @brief enable or disable FCP response doublicate filtering 
     347     * 
     348     * this is use only for devices (e.g. edirol fa101) which have a  
     349     * buggy FCP implementation and send more then one FCP response  
     350     * for one request.  
     351     */ 
     352    void setFCPResponseFiltering(bool enable); 
    277353 
    278354// ISO channel stuff 
     
    312388    raw1394handle_t getHandle() {return m_handle;}; 
    313389 
     390protected: 
     391    Util::Configuration     *m_configuration; 
     392 
    314393private: 
     394    bool configurationUpdated(); 
     395 
    315396    bool startRHThread(); 
    316397    void stopRHThread(); 
     
    349430    bool                    m_have_new_ctr_read; 
    350431 
     432    bool            m_filterFCPResponse; 
     433 
    351434    // the RT watchdog 
    352435    Util::Watchdog*     m_pWatchdog; 
     
    360443    typedef std::vector< ARMHandler * > arm_handler_vec_t; 
    361444    arm_handler_vec_t m_armHandlers; 
     445 
     446    // unprotected variants 
     447    bool writeNoLock( fb_nodeid_t nodeId, 
     448        fb_nodeaddr_t addr, 
     449        size_t length, 
     450        fb_quadlet_t* data ); 
     451    bool readNoLock( fb_nodeid_t nodeId, 
     452           fb_nodeaddr_t addr, 
     453           size_t length, 
     454           fb_quadlet_t* buffer ); 
     455 
     456    // FCP transaction support 
     457    static int _avc_fcp_handler(raw1394handle_t handle, nodeid_t nodeid,  
     458                                int response, size_t length, 
     459                                unsigned char *data); 
     460    int handleFcpResponse(nodeid_t nodeid, 
     461                          int response, size_t length, 
     462                          unsigned char *data); 
     463 
     464    enum eFcpStatus { 
     465        eFS_Empty, 
     466        eFS_Waiting, 
     467        eFS_Responded, 
     468        eFS_Error, 
     469    }; 
     470 
     471    struct sFcpBlock { 
     472        enum eFcpStatus status; 
     473        nodeid_t target_nodeid; 
     474        unsigned int request_length; 
     475        quadlet_t request[MAX_FCP_BLOCK_SIZE_QUADS]; 
     476        unsigned int response_length; 
     477        quadlet_t response[MAX_FCP_BLOCK_SIZE_QUADS]; 
     478    }; 
     479    struct sFcpBlock m_fcp_block; 
     480 
     481    bool doFcpTransaction(); 
     482    bool doFcpTransactionTry(); 
    362483 
    363484public: 
  • trunk/libffado/src/libieee1394/IsoHandler.cpp

    r1348 r1498  
    8181   , m_last_now( 0xFFFFFFFF ) 
    8282   , m_last_packet_handled_at( 0xFFFFFFFF ) 
     83   , m_receive_mode ( RAW1394_DMA_PACKET_PER_BUFFER ) 
    8384   , m_Client( 0 ) 
    8485   , m_speed( RAW1394_ISO_SPEED_400 ) 
     
    106107   , m_last_now( 0xFFFFFFFF ) 
    107108   , m_last_packet_handled_at( 0xFFFFFFFF ) 
     109   , m_receive_mode ( RAW1394_DMA_PACKET_PER_BUFFER ) 
    108110   , m_Client( 0 ) 
    109111   , m_speed( RAW1394_ISO_SPEED_400 ) 
     
    131133   , m_last_now( 0xFFFFFFFF ) 
    132134   , m_last_packet_handled_at( 0xFFFFFFFF ) 
     135   , m_receive_mode ( RAW1394_DMA_PACKET_PER_BUFFER ) 
    133136   , m_Client( 0 ) 
    134137   , m_speed( speed ) 
     
    376379                    unsigned char channel, unsigned char tag, unsigned char sy, 
    377380                    unsigned int cycle, unsigned int dropped) { 
    378  
    379381    // keep track of dropped cycles 
    380382    int dropped_cycles = 0; 
     
    396398    m_last_cycle = cycle; 
    397399 
    398     uint32_t pkt_ctr = cycle << 12; 
    399  
    400     // if we assume that one iterate() loop doesn't take longer than 0.5 seconds, 
    401     // the seconds field won't change while the iterate loop runs 
    402     // this means that we can preset 'now' before running iterate() 
    403     uint32_t now_secs = CYCLE_TIMER_GET_SECS(m_last_now); 
    404     // causality results in the fact that 'now' is always after 'cycle' 
    405     // except if additional packets are received between setting the 
    406     // m_last_now and the starting the iterate() loop. 
    407     // this causes the m_last_now to be set at a time before the last packet 
    408     // in this loop is received. however, it's not going to be >4000 cycles. 
    409     // hence: 
    410     // - if the m_last_now > cycle, there is no need to unwrap 
    411     //   both values are within the same second 
    412     // - if m_last_now < cycle it can mean two things: 
    413     //    * m_last_now has wrapped, but is still later than cycle 
    414     //      hence diffCycles(m_last_now, cycle) > 0. We should unwrap 
    415     //    * m_last_now has not wrapped, and cycle is ahead of m_last_now 
    416     //      this means that the cycle is more recent than the saved 
    417     //      m_last_now value 
    418     // . Hence if we calculate 
    419     // the unwrapped difference, and it's larger than 0, this means 
    420     // that m_last_now is after the current cycle. . 
    421     // it m_last_now is before the current cycle, we should not unwrap 
    422     // NOTE: another option is to reread the m_last_now 
    423     if( (CYCLE_TIMER_GET_CYCLES(m_last_now) < cycle) 
    424         && diffCycles(CYCLE_TIMER_GET_CYCLES(m_last_now), cycle) >= 0) { 
    425         debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 
    426                            "unwrapping %d => %d, %d\n", 
    427                            CYCLE_TIMER_GET_CYCLES(m_last_now), 
    428                            cycle); 
    429         // the cycle field has wrapped, substract one second 
    430         if(now_secs == 0) { 
    431             now_secs = 127; 
    432         } else  { 
    433             now_secs -= 1; 
    434         } 
    435     } 
    436  
     400    // the m_last_now value is set when the iterate() function is called. 
     401    uint32_t now_cycles = CYCLE_TIMER_GET_CYCLES(m_last_now); 
     402 
     403    // two cases can occur: 
     404    // (1) this packet has been received before iterate() was called (normal case). 
     405    // (2) this packet has been received after iterate() was called. 
     406    //     happens when the kernel flushes more packets while we are already processing. 
     407    // 
     408    // In case (1) now_cycles is a small number of cycles larger than cycle. In 
     409    // case (2) now_cycles is a small number of cycles smaller than cycle. 
     410    // hence  abs(diffCycles(now_cycles, cycles)) has to be 'small' 
     411 
     412    // we can calculate the time of arrival for this packet as 
     413    // 'now' + diffCycles(cycles, now_cycles) * TICKS_PER_CYCLE 
     414    // in its properly wrapped version 
     415    int64_t diff_cycles = diffCycles(cycle, now_cycles); 
     416    int64_t tmp = CYCLE_TIMER_TO_TICKS(m_last_now); 
     417    tmp += diff_cycles * (int64_t)TICKS_PER_CYCLE; 
     418    uint64_t pkt_ctr_ticks = wrapAtMinMaxTicks(tmp); 
     419    uint32_t pkt_ctr = TICKS_TO_CYCLE_TIMER(pkt_ctr_ticks); 
    437420    #ifdef DEBUG 
    438     if( (CYCLE_TIMER_GET_CYCLES(m_last_now) < cycle) 
    439         && diffCycles(CYCLE_TIMER_GET_CYCLES(m_last_now), cycle) < 0 
     421    if( (now_cycles < cycle) 
     422        && diffCycles(now_cycles, cycle) < 0 
    440423        // ignore this on dropped cycles, since it's normal 
    441424        // that now is ahead on the received packets (as we miss packets) 
     
    445428    } 
    446429    #endif 
    447     pkt_ctr |= (now_secs & 0x7F) << 25; 
    448430 
    449431    #if ISOHANDLER_CHECK_CTR_RECONSTRUCTION 
     
    465447    pkt_ctr_ref |= (now_secs_ref & 0x7F) << 25; 
    466448 
    467     if(pkt_ctr != pkt_ctr_ref) { 
     449    if((pkt_ctr & ~0x0FFFL) != pkt_ctr_ref) { 
    468450        debugWarning("reconstructed CTR counter discrepancy\n"); 
    469         debugWarning(" ingredients: %X, %lX, %lX, %lX, %lX, %ld, %ld\n", 
    470                        cycle, pkt_ctr_ref, pkt_ctr, now, m_last_now, now_secs_ref, now_secs); 
     451        debugWarning(" ingredients: %X, %lX, %lX, %lX, %lX, %ld, %ld, %ld, %lld\n", 
     452                       cycle, pkt_ctr_ref, pkt_ctr, now, m_last_now, now_secs_ref, CYCLE_TIMER_GET_SECS(now), CYCLE_TIMER_GET_SECS(m_last_now), tmp); 
     453        debugWarning(" diffcy = %ld \n", diff_cycles); 
    471454    } 
    472455    #endif 
     
    520503        pkt_ctr = 0xFFFFFFFF; 
    521504    } else { 
    522         pkt_ctr = cycle << 12; 
    523  
    524         // if we assume that one iterate() loop doesn't take longer than 0.5 seconds, 
    525         // the seconds field won't change while the iterate loop runs 
    526         // this means that we can preset 'now' before running iterate() 
    527         uint32_t now_secs = CYCLE_TIMER_GET_SECS(m_last_now); 
    528         // causality results in the fact that 'now' is always after 'cycle' 
    529         if(CYCLE_TIMER_GET_CYCLES(m_last_now) > (unsigned int)cycle) { 
    530             // the cycle field has wrapped, add one second 
    531             now_secs += 1; 
    532             // no need for this: 
    533             //if(now_secs == 128) { 
    534             //    now_secs = 0; 
    535             //} 
    536             // since we mask later on 
    537         } 
    538         pkt_ctr |= (now_secs & 0x7F) << 25; 
     505        // the m_last_now value is set when the iterate() function is called. 
     506        uint32_t now_cycles = CYCLE_TIMER_GET_CYCLES(m_last_now); 
     507 
     508        // two cases can occur: 
     509        // (1) this packet has been received before iterate() was called (normal case). 
     510        // (2) this packet has been received after iterate() was called. 
     511        //     happens when the kernel flushes more packets while we are already processing. 
     512        // 
     513        // In case (1) now_cycles is a small number of cycles larger than cycle. In 
     514        // case (2) now_cycles is a small number of cycles smaller than cycle. 
     515        // hence  abs(diffCycles(now_cycles, cycles)) has to be 'small' 
     516 
     517        // we can calculate the time of arrival for this packet as 
     518        // 'now' + diffCycles(cycles, now_cycles) * TICKS_PER_CYCLE 
     519        // in its properly wrapped version 
     520        int64_t diff_cycles = diffCycles(cycle, now_cycles); 
     521        int64_t tmp = CYCLE_TIMER_TO_TICKS(m_last_now); 
     522        tmp += diff_cycles * (int64_t)TICKS_PER_CYCLE; 
     523        uint64_t pkt_ctr_ticks = wrapAtMinMaxTicks(tmp); 
     524        pkt_ctr = TICKS_TO_CYCLE_TIMER(pkt_ctr_ticks); 
    539525 
    540526        #if ISOHANDLER_CHECK_CTR_RECONSTRUCTION 
     
    547533            now_secs_ref += 1; 
    548534            // no need for this: 
    549             //if(now_secs == 128) { 
    550             //    now_secs = 0; 
    551             //} 
    552             // since we mask later on 
     535            if(now_secs_ref == 128) { 
     536               now_secs_ref = 0; 
     537            } 
    553538        } 
    554539        uint32_t pkt_ctr_ref = cycle << 12; 
    555540        pkt_ctr_ref |= (now_secs_ref & 0x7F) << 25; 
    556541 
    557         if(pkt_ctr != pkt_ctr_ref) { 
     542        if((pkt_ctr & ~0x0FFFL) != pkt_ctr_ref) { 
    558543            debugWarning("reconstructed CTR counter discrepancy\n"); 
    559             pkt_ctr=pkt_ctr_ref; 
     544            debugWarning(" ingredients: %X, %lX, %lX, %lX, %lX, %ld, %ld, %ld, %lld\n", 
     545                        cycle, pkt_ctr_ref, pkt_ctr, now, m_last_now, now_secs_ref, CYCLE_TIMER_GET_SECS(now), CYCLE_TIMER_GET_SECS(m_last_now), tmp); 
     546            debugWarning(" diffcy = %ld \n", diff_cycles); 
    560547        } 
    561548        #endif 
     
    675662                                m_max_packet_size, 
    676663                                m_Client->getChannel(), 
    677                                 RAW1394_DMA_PACKET_PER_BUFFER
     664                                m_receive_mode
    678665                                m_irq_interval)) { 
    679             debugFatal("Could not do receive initialisation (DMA_BUFFERFILL)!\n" ); 
     666            debugFatal("Could not do receive initialisation!\n" ); 
    680667            debugFatal("  %s\n",strerror(errno)); 
    681668            return false; 
     
    728715    // indicate that the first iterate() still has to occur. 
    729716    m_last_now = 0xFFFFFFFF; 
     717    m_last_packet_handled_at = 0xFFFFFFFF; 
    730718 
    731719    m_State = E_Running; 
  • trunk/libffado/src/libieee1394/IsoHandler.h

    r1348 r1498  
    168168    uint32_t getLastPacketTime() {return m_last_packet_handled_at;}; 
    169169 
     170    /** 
     171     * @brief set iso receive mode. doesn't have any effect if the stream is running 
     172     * @param m receive mode 
     173     */ 
     174    void setReceiveMode(enum raw1394_iso_dma_recv_mode m) 
     175        {m_receive_mode = m;} 
     176 
    170177    void notifyOfDeath(); 
    171178    bool handleBusReset(); 
     
    181188    uint32_t        m_last_now; 
    182189    uint32_t        m_last_packet_handled_at; 
     190    enum raw1394_iso_dma_recv_mode m_receive_mode; 
    183191 
    184192    Streaming::StreamProcessor *m_Client; // FIXME: implement with functors 
  • trunk/libffado/src/libieee1394/IsoHandlerManager.cpp

    r1348 r1498  
    3333#include "libutil/SystemTimeSource.h" 
    3434#include "libutil/Watchdog.h" 
     35#include "libutil/Configuration.h" 
    3536 
    3637#include <cstring> 
     
    5051    , m_running( false ) 
    5152    , m_in_busreset( false ) 
     53    , m_activity_wait_timeout_nsec (ISOHANDLERMANAGER_ISO_TASK_WAIT_TIMEOUT_USECS * 1000LL) 
    5254{ 
    5355} 
     
    344346        } 
    345347    } 
     348 
    346349    if(handler_died) { 
    347350        m_running = false; 
     
    389392    struct timespec ts; 
    390393    int result; 
    391     long long int timeout_nsec = ISOHANDLERMANAGER_ISO_TASK_WAIT_TIMEOUT_USECS * 1000LL; 
    392394 
    393395    if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { 
     
    396398    } 
    397399 
    398     ts.tv_nsec += timeout_nsec; 
     400    ts.tv_nsec += m_activity_wait_timeout_nsec; 
    399401    while(ts.tv_nsec >= 1000000000LL) { 
    400402        ts.tv_sec += 1; 
     
    419421                        this, result); 
    420422            debugError("(%p) timeout_nsec=%lld ts.sec=%d ts.nsec=%lld\n",  
    421                        this, timeout_nsec, ts.tv_sec, ts.tv_nsec); 
     423                       this, m_activity_wait_timeout_nsec, ts.tv_sec, ts.tv_nsec); 
    422424            return eAR_Error; 
    423425        } else { 
     
    425427                        this, result, errno); 
    426428            debugError("(%p) timeout_nsec=%lld ts.sec=%d ts.nsec=%lld\n",  
    427                        this, timeout_nsec, ts.tv_sec, ts.tv_nsec); 
     429                       this, m_activity_wait_timeout_nsec, ts.tv_sec, ts.tv_nsec); 
    428430            return eAR_Error; 
    429431        } 
     
    533535    debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) switch to: (rt=%d, prio=%d)...\n", this, rt, priority); 
    534536    if (priority > THREAD_MAX_RTPRIO) priority = THREAD_MAX_RTPRIO; // cap the priority 
     537    if (priority < THREAD_MIN_RTPRIO) priority = THREAD_MIN_RTPRIO; // cap the priority 
    535538    m_realtime = rt; 
    536539    m_priority = priority; 
     540 
     541    // grab the options from the parent 
     542    Util::Configuration *config = m_service.getConfiguration(); 
     543    int ihm_iso_prio_increase = ISOHANDLERMANAGER_ISO_PRIO_INCREASE; 
     544    int ihm_iso_prio_increase_xmit = ISOHANDLERMANAGER_ISO_PRIO_INCREASE_XMIT; 
     545    int ihm_iso_prio_increase_recv = ISOHANDLERMANAGER_ISO_PRIO_INCREASE_RECV; 
     546    if(config) { 
     547        config->getValueForSetting("ieee1394.isomanager.prio_increase", ihm_iso_prio_increase); 
     548        config->getValueForSetting("ieee1394.isomanager.prio_increase_xmit", ihm_iso_prio_increase_xmit); 
     549        config->getValueForSetting("ieee1394.isomanager.prio_increase_recv", ihm_iso_prio_increase_recv); 
     550    } 
    537551 
    538552    if (m_IsoThreadTransmit) { 
    539553        if (m_realtime) { 
    540554            m_IsoThreadTransmit->AcquireRealTime(m_priority 
    541                                                  + ISOHANDLERMANAGER_ISO_PRIO_INCREASE 
    542                                                  + ISOHANDLERMANAGER_ISO_PRIO_INCREASE_XMIT); 
     555                                                 + ihm_iso_prio_increase 
     556                                                 + ihm_iso_prio_increase_xmit); 
    543557        } else { 
    544558            m_IsoThreadTransmit->DropRealTime(); 
     
    548562        if (m_realtime) { 
    549563            m_IsoThreadReceive->AcquireRealTime(m_priority  
    550                                                 + ISOHANDLERMANAGER_ISO_PRIO_INCREASE 
    551                                                 + ISOHANDLERMANAGER_ISO_PRIO_INCREASE_RECV); 
     564                                                + ihm_iso_prio_increase 
     565                                                + ihm_iso_prio_increase_recv); 
    552566        } else { 
    553567            m_IsoThreadReceive->DropRealTime(); 
     
    565579        debugError("Manager already initialized...\n"); 
    566580        return false; 
     581    } 
     582 
     583    // grab the options from the parent 
     584    Util::Configuration *config = m_service.getConfiguration(); 
     585    int ihm_iso_prio_increase = ISOHANDLERMANAGER_ISO_PRIO_INCREASE; 
     586    int ihm_iso_prio_increase_xmit = ISOHANDLERMANAGER_ISO_PRIO_INCREASE_XMIT; 
     587    int ihm_iso_prio_increase_recv = ISOHANDLERMANAGER_ISO_PRIO_INCREASE_RECV; 
     588    int64_t isotask_activity_timeout_usecs = ISOHANDLERMANAGER_ISO_TASK_WAIT_TIMEOUT_USECS; 
     589    if(config) { 
     590        config->getValueForSetting("ieee1394.isomanager.prio_increase", ihm_iso_prio_increase); 
     591        config->getValueForSetting("ieee1394.isomanager.prio_increase_xmit", ihm_iso_prio_increase_xmit); 
     592        config->getValueForSetting("ieee1394.isomanager.prio_increase_recv", ihm_iso_prio_increase_recv); 
     593        config->getValueForSetting("ieee1394.isomanager.isotask_activity_timeout_usecs", isotask_activity_timeout_usecs); 
    567594    } 
    568595 
     
    575602    } 
    576603    m_IsoTaskTransmit->setVerboseLevel(getDebugLevel()); 
     604    m_IsoTaskTransmit->m_activity_wait_timeout_nsec = isotask_activity_timeout_usecs * 1000LL; 
    577605    m_IsoThreadTransmit = new Util::PosixThread(m_IsoTaskTransmit, "ISOXMT", m_realtime, 
    578                                                 m_priority + ISOHANDLERMANAGER_ISO_PRIO_INCREASE 
    579                                                 + ISOHANDLERMANAGER_ISO_PRIO_INCREASE_XMIT
     606                                                m_priority + ihm_iso_prio_increase 
     607                                                + ihm_iso_prio_increase_xmit
    580608                                                PTHREAD_CANCEL_DEFERRED); 
    581609 
     
    594622    m_IsoTaskReceive->setVerboseLevel(getDebugLevel()); 
    595623    m_IsoThreadReceive = new Util::PosixThread(m_IsoTaskReceive, "ISORCV", m_realtime, 
    596                                                m_priority + ISOHANDLERMANAGER_ISO_PRIO_INCREASE 
    597                                                + ISOHANDLERMANAGER_ISO_PRIO_INCREASE_RECV
     624                                               m_priority + ihm_iso_prio_increase 
     625                                               + ihm_iso_prio_increase_recv
    598626                                               PTHREAD_CANCEL_DEFERRED); 
    599627 
     
    759787    // allocate a handler for this stream 
    760788    if (stream->getType()==StreamProcessor::ePT_Receive) { 
     789        // grab the options from the parent 
     790        Util::Configuration *config = m_service.getConfiguration(); 
     791        int receive_mode_setting = DEFAULT_ISO_RECEIVE_MODE; 
     792        int bufferfill_mode_threshold = BUFFERFILL_MODE_THRESHOLD; 
     793        int min_interrupts_per_period = MINIMUM_INTERRUPTS_PER_PERIOD; 
     794        int max_nb_buffers_recv = MAX_RECV_NB_BUFFERS; 
     795        int min_packetsize_recv = MIN_RECV_PACKET_SIZE; 
     796        if(config) { 
     797            config->getValueForSetting("ieee1394.isomanager.iso_receive_mode", receive_mode_setting); 
     798            config->getValueForSetting("ieee1394.isomanager.bufferfill_mode_threshold", bufferfill_mode_threshold); 
     799            config->getValueForSetting("ieee1394.isomanager.min_interrupts_per_period", min_interrupts_per_period); 
     800            config->getValueForSetting("ieee1394.isomanager.max_nb_buffers_recv", max_nb_buffers_recv); 
     801            config->getValueForSetting("ieee1394.isomanager.min_packetsize_recv", min_packetsize_recv); 
     802        } 
     803 
    761804        // setup the optimal parameters for the raw1394 ISO buffering 
    762805        unsigned int packets_per_period = stream->getPacketsPerPeriod(); 
    763         unsigned int max_packet_size = stream->getMaxPacketSize() + 8; // bufferfill takes another 8 bytes for headers 
     806        // reserve space for the 1394 header too (might not be necessary) 
     807        unsigned int max_packet_size = stream->getMaxPacketSize() + 8; 
    764808        unsigned int page_size = getpagesize(); 
     809 
     810        enum raw1394_iso_dma_recv_mode receive_mode; 
     811        switch(receive_mode_setting) { 
     812            case 0: 
     813                if(packets_per_period < (unsigned)bufferfill_mode_threshold) { 
     814                    debugOutput( DEBUG_LEVEL_VERBOSE, "Using packet-per-buffer mode (auto) [%d, %d]\n", 
     815                                 packets_per_period, bufferfill_mode_threshold); 
     816                    receive_mode = RAW1394_DMA_PACKET_PER_BUFFER; 
     817                } else { 
     818                    debugOutput( DEBUG_LEVEL_VERBOSE, "Using bufferfill mode (auto) [%d, %d]\n", 
     819                                 packets_per_period, bufferfill_mode_threshold); 
     820                    receive_mode = RAW1394_DMA_BUFFERFILL; 
     821                } 
     822                break; 
     823            case 1:  
     824                debugOutput( DEBUG_LEVEL_VERBOSE, "Using packet-per-buffer mode (config)\n"); 
     825                receive_mode = RAW1394_DMA_PACKET_PER_BUFFER; 
     826                break; 
     827            case 2: 
     828                debugOutput( DEBUG_LEVEL_VERBOSE, "Using bufferfill mode (config)\n"); 
     829                receive_mode = RAW1394_DMA_BUFFERFILL; 
     830                break; 
     831            default: debugWarning("Bogus receive mode setting in config: %d\n", receive_mode_setting); 
     832        } 
    765833 
    766834        // Ensure we don't request a packet size bigger than the 
     
    771839            return false; 
    772840        } 
     841        if (max_packet_size < (unsigned)min_packetsize_recv) { 
     842            debugError("min packet size (%u) < MIN_RECV_PACKET_SIZE (%u), using min value\n", 
     843                       max_packet_size, min_packetsize_recv); 
     844            max_packet_size = min_packetsize_recv; 
     845        } 
    773846 
    774847        // the interrupt/wakeup interval prediction of raw1394 is a mess... 
    775         int irq_interval = (packets_per_period-1) / MINIMUM_INTERRUPTS_PER_PERIOD
     848        int irq_interval = (packets_per_period-1) / min_interrupts_per_period
    776849        if(irq_interval <= 0) irq_interval=1; 
    777850 
    778851        // the receive buffer size doesn't matter for the latency, 
    779         // but it has a minimal value in order for libraw to operate correctly (300) 
    780         int buffers=400; 
     852        // it does seem to be confined to a certain region for correct 
     853        // operation. However it is not clear how many. 
     854        int buffers = max_nb_buffers_recv; 
     855 
     856        // ensure at least 2 hardware interrupts per ISO buffer wraparound 
     857        if(irq_interval > buffers/2) { 
     858            irq_interval = buffers/2; 
     859        } 
    781860 
    782861        // create the actual handler 
     862        debugOutput( DEBUG_LEVEL_VERBOSE, " creating IsoRecvHandler\n"); 
    783863        h = new IsoHandler(*this, IsoHandler::eHT_Receive, 
    784864                           buffers, max_packet_size, irq_interval); 
    785  
    786         debugOutput( DEBUG_LEVEL_VERBOSE, " creating IsoRecvHandler\n"); 
    787865 
    788866        if(!h) { 
     
    791869        } 
    792870 
     871        h->setReceiveMode(receive_mode); 
     872 
    793873    } else if (stream->getType()==StreamProcessor::ePT_Transmit) { 
     874        // grab the options from the parent 
     875        Util::Configuration *config = m_service.getConfiguration(); 
     876        int min_interrupts_per_period = MINIMUM_INTERRUPTS_PER_PERIOD; 
     877        int max_nb_buffers_xmit = MAX_XMIT_NB_BUFFERS; 
     878        int max_packetsize_xmit = MAX_XMIT_PACKET_SIZE; 
     879        int min_packetsize_xmit = MIN_XMIT_PACKET_SIZE; 
     880        if(config) { 
     881            config->getValueForSetting("ieee1394.isomanager.min_interrupts_per_period", min_interrupts_per_period); 
     882            config->getValueForSetting("ieee1394.isomanager.max_nb_buffers_xmit", max_nb_buffers_xmit); 
     883            config->getValueForSetting("ieee1394.isomanager.max_packetsize_xmit", max_packetsize_xmit); 
     884            config->getValueForSetting("ieee1394.isomanager.min_packetsize_xmit", min_packetsize_xmit); 
     885        } 
     886 
    794887        // setup the optimal parameters for the raw1394 ISO buffering 
    795 //        unsigned int packets_per_period = stream->getPacketsPerPeriod(); 
    796         unsigned int max_packet_size = stream->getMaxPacketSize(); 
    797 //         unsigned int page_size = getpagesize(); 
    798  
    799         // Ensure we don't request a packet size bigger than the 
    800         // kernel-enforced maximum which is currently 1 page. 
    801 //         if (max_packet_size > page_size) { 
    802 //             debugError("max packet size (%u) > page size (%u)\n", max_packet_size, page_size); 
    803 //             return false; 
    804 //         } 
    805         if (max_packet_size > MAX_XMIT_PACKET_SIZE) { 
     888        // reserve space for the 1394 header too (might not be necessary) 
     889        unsigned int max_packet_size = stream->getMaxPacketSize() + 8; 
     890 
     891        if (max_packet_size > (unsigned)max_packetsize_xmit) { 
    806892            debugError("max packet size (%u) > MAX_XMIT_PACKET_SIZE (%u)\n", 
    807                        max_packet_size, MAX_XMIT_PACKET_SIZE); 
     893                       max_packet_size, max_packetsize_xmit); 
    808894            return false; 
    809895        } 
    810  
    811         // the SP specifies how many packets to ISO-buffer 
    812         int buffers = stream->getNbPacketsIsoXmitBuffer(); 
    813         if (buffers > MAX_XMIT_NB_BUFFERS) { 
    814             debugOutput(DEBUG_LEVEL_VERBOSE, 
    815                         "nb buffers (%u) > MAX_XMIT_NB_BUFFERS (%u)\n", 
    816                         buffers, MAX_XMIT_NB_BUFFERS)
    817             buffers = MAX_XMIT_NB_BUFFERS
    818         } 
    819         unsigned int irq_interval = buffers / MINIMUM_INTERRUPTS_PER_PERIOD
     896        if (max_packet_size < (unsigned)min_packetsize_xmit) { 
     897            debugError("min packet size (%u) < MIN_XMIT_PACKET_SIZE (%u), using min value\n", 
     898                       max_packet_size, min_packetsize_xmit); 
     899            max_packet_size = min_packetsize_xmit; 
     900        } 
     901 
     902        int buffers = max_nb_buffers_xmit
     903        unsigned int packets_per_period = stream->getPacketsPerPeriod()
     904 
     905        int irq_interval = (packets_per_period-1) / min_interrupts_per_period
    820906        if(irq_interval <= 0) irq_interval=1; 
     907        // ensure at least 2 hardware interrupts per ISO buffer wraparound 
     908        if(irq_interval > buffers/2) { 
     909            irq_interval = buffers/2; 
     910        } 
    821911 
    822912        debugOutput( DEBUG_LEVEL_VERBOSE, " creating IsoXmitHandler\n"); 
  • trunk/libffado/src/libieee1394/IsoHandlerManager.h

    r1336 r1498  
    5858class IsoTask : public Util::RunnableInterface 
    5959{ 
     60    friend class IsoHandlerManager; 
    6061    public: 
    6162        IsoTask(IsoHandlerManager& manager, enum IsoHandler::EHandlerType); 
     
    114115#endif 
    115116 
    116         // activity signaling 
    117         sem_t m_activity_semaphore; 
    118  
    119117        enum IsoHandler::EHandlerType m_handlerType; 
    120118        bool m_running; 
    121119        bool m_in_busreset; 
     120 
     121        // activity signaling 
     122        sem_t m_activity_semaphore; 
     123        long long int m_activity_wait_timeout_nsec; 
    122124 
    123125        // debug stuff 
     
    198200         */ 
    199201        bool handleBusReset(); 
     202 
    200203    // the state machine 
    201204    private: 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp

    r1348 r1498  
    6767} 
    6868 
    69 unsigned int 
    70 AmdtpReceiveStreamProcessor::getAveragePacketSize() 
    71 { 
    72     // in one second we have 8000 packets 
    73     // containing FRAMERATE frames of m_dimension quadlets 
    74     // so 8000 packet headers + FRAMERATE*m_dimension quadlets 
    75     unsigned int one_second = 8000 * 2 * sizeof(quadlet_t) + m_StreamProcessorManager.getNominalRate() * m_dimension * sizeof(quadlet_t); 
    76     return one_second / 8000; 
    77 } 
    78  
    7969bool AmdtpReceiveStreamProcessor::prepareChild() { 
    8070    debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing (%p)...\n", this); 
     
    389379                    sample_int |= 0x01000000; // flag that there is a midi event present 
    390380                    *buffer = sample_int; 
    391                     debugOutput(DEBUG_LEVEL_VERBOSE, "Received midi byte %08X on port %p index %d\n", sample_int, p, j-p.location); 
     381                    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Received midi byte %08X on port %p index %d\n", sample_int, p, j-p.location); 
    392382                } else { 
    393383                    // make sure no event is received 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.h

    r1348 r1498  
    9090    virtual unsigned int getMaxPacketSize()  
    9191                    {return 4 * (2 + getSytInterval() * m_dimension);}; 
    92     virtual unsigned int getAveragePacketSize(); 
    9392    virtual unsigned int getEventsPerFrame()  
    9493                    { return m_dimension; }; 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp

    r1348 r1498  
    4040#include <cstring> 
    4141 
    42 #define AMDTP_FLOAT_MULTIPLIER 2147483392.0 
    43  
     42#define likely(x)   __builtin_expect((x),1) 
     43#define unlikely(x) __builtin_expect((x),0) 
     44 
     45#define AMDTP_FLOAT_MULTIPLIER (1.0f * ((1<<23) - 1)) 
    4446namespace Streaming 
    4547{ 
     
    408410 
    409411unsigned int 
    410 AmdtpTransmitStreamProcessor::getAveragePacketSize() 
    411 { 
    412     // in one second we have 8000 packets 
    413     // containing FRAMERATE frames of m_dimension quadlets 
    414     // so 8000 packet headers + FRAMERATE*m_dimension quadlets 
    415     unsigned int one_second = 8000 * 2 * sizeof(quadlet_t) + m_StreamProcessorManager.getNominalRate() * m_dimension * sizeof(quadlet_t); 
    416     return one_second / 8000; 
    417 } 
    418  
    419 unsigned int 
    420412AmdtpTransmitStreamProcessor::getFDF() { 
    421413    switch (m_StreamProcessorManager.getNominalRate()) { 
     
    517509 
    518510#ifdef __SSE2__ 
    519 //#if 0 
    520511#include <emmintrin.h> 
    521512#warning SSE2 build 
     
    545536 
    546537    const __m128i label = _mm_set_epi32 (0x40000000, 0x40000000, 0x40000000, 0x40000000); 
     538    const __m128i mask = _mm_set_epi32 (0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF); 
    547539    const __m128 mult = _mm_set_ps(AMDTP_FLOAT_MULTIPLIER, AMDTP_FLOAT_MULTIPLIER, AMDTP_FLOAT_MULTIPLIER, AMDTP_FLOAT_MULTIPLIER); 
    548540 
     
    560552        for (j=0; j<4; j++) { 
    561553            p = &(m_audio_ports.at(i+j)); 
    562             if(p->buffer && p->enabled) { 
     554            if(likely(p->buffer && p->enabled)) { 
    563555                client_buffers[j] = (float *) p->buffer; 
    564556                client_buffers[j] += offset; 
     
    572564        // the base event for this position 
    573565        target_event = (quadlet_t *)(data + i); 
    574  
    575566        // process the events 
    576567        for (j=0;j < nevents; j += 1) 
     
    598589            // convert to signed integer 
    599590            v_int = _mm_cvttps_epi32( v_float ); 
    600             // shift right 8 bits 
    601             v_int = _mm_srli_epi32( v_int, 8 ); 
     591            // mask 
     592            v_int = _mm_and_si128( v_int, mask ); 
    602593            // label it 
    603594            v_int = _mm_or_si128( v_int, label ); 
     
    608599            // do second swap 
    609600            v_int = _mm_or_si128( _mm_slli_epi32( v_int, 16 ), _mm_srli_epi32( v_int, 16 ) ); 
    610  
    611601            // store the packed int 
    612602            // (target misalignment is assumed since we don't know the m_dimension) 
     
    631621        assert(nevents + offset <= p.buffer_size ); 
    632622 
    633         if(p.buffer && p.enabled) { 
     623        if(likely(p.buffer && p.enabled)) { 
    634624            float *buffer = (float *)(p.buffer); 
    635625            buffer += offset; 
     
    656646                v_float = _mm_min_ps(v_float, v_max); 
    657647#endif 
    658  
    659648                // multiply 
    660649                v_float = _mm_mul_ps(v_float, mult); 
    661650                // convert to signed integer 
    662651                v_int = _mm_cvttps_epi32( v_float ); 
    663                 // shift right 8 bits 
    664                 v_int = _mm_srli_epi32( v_int, 8 ); 
     652                // mask 
     653                v_int = _mm_and_si128( v_int, mask ); 
    665654                // label it 
    666655                v_int = _mm_or_si128( v_int, label ); 
     
    690679                float *in = (float *)buffer; 
    691680#if AMDTP_CLIP_FLOATS 
    692                 if(*in > 1.0) *in=1.0; 
    693                 if(*in < -1.0) *in=-1.0; 
    694 #endif 
     681                // clip directly to the value of a maxed event 
     682                if(unlikely(*in > 1.0)) { 
     683                    *target_event = CONDSWAPTOBUS32_CONST(0x407FFFFF); 
     684                } else if(unlikely(*in < -1.0)) { 
     685                    *target_event = CONDSWAPTOBUS32_CONST(0x40800001); 
     686                } else { 
     687                    float v = (*in) * AMDTP_FLOAT_MULTIPLIER; 
     688                    unsigned int tmp = ((int) v); 
     689                    tmp = ( tmp & 0x00FFFFFF ) | 0x40000000; 
     690                    *target_event = CondSwapToBus32((quadlet_t)tmp); 
     691                } 
     692#else 
    695693                float v = (*in) * AMDTP_FLOAT_MULTIPLIER; 
    696694                unsigned int tmp = ((int) v); 
    697                 tmp = ( tmp >> 8 ) | 0x40000000; 
     695                tmp = ( tmp & 0x00FFFFFF ) | 0x40000000; 
    698696                *target_event = CondSwapToBus32((quadlet_t)tmp); 
     697#endif 
    699698                buffer++; 
    700699                target_event += m_dimension; 
     
    746745        for (j=0; j<4; j++) { 
    747746            p = &(m_audio_ports.at(i+j)); 
    748             if(p->buffer && p->enabled) { 
     747            if(likely(p->buffer && p->enabled)) { 
    749748                client_buffers[j] = (uint32_t *) p->buffer; 
    750749                client_buffers[j] += offset; 
     
    805804        assert(nevents + offset <= p.buffer_size ); 
    806805 
    807         if(p.buffer && p.enabled) { 
     806        if(likely(p.buffer && p.enabled)) { 
    808807            uint32_t *buffer = (uint32_t *)(p.buffer); 
    809808            buffer += offset; 
     
    890889        assert(nevents + offset <= p.buffer_size ); 
    891890 
    892         if(p.buffer && p.enabled) { 
     891        if(likely(p.buffer && p.enabled)) { 
    893892            quadlet_t *buffer = (quadlet_t *)(p.buffer); 
    894893            buffer += offset; 
     
    931930        assert(nevents + offset <= p.buffer_size ); 
    932931 
    933         if(p.buffer && p.enabled) { 
     932        if(likely(p.buffer && p.enabled)) { 
    934933            quadlet_t *buffer = (quadlet_t *)(p.buffer); 
    935934            buffer += offset; 
     
    939938                float *in = (float *)buffer; 
    940939#if AMDTP_CLIP_FLOATS 
    941                 if(*in > 1.0) *in=1.0; 
    942                 if(*in < -1.0) *in=-1.0; 
     940                // clip directly to the value of a maxed event 
     941                if(unlikely(*in > 1.0)) { 
     942                    *target_event = CONDSWAPTOBUS32_CONST(0x407FFFFF); 
     943                } else if(unlikely(*in < -1.0)) { 
     944                    *target_event = CONDSWAPTOBUS32_CONST(0x40800001); 
     945                } else { 
     946                    float v = (*in) * AMDTP_FLOAT_MULTIPLIER; 
     947                    unsigned int tmp = ((int) v); 
     948                    tmp = ( tmp & 0x00FFFFFF ) | 0x40000000; 
     949                    *target_event = CondSwapToBus32((quadlet_t)tmp); 
     950                } 
     951#else 
     952                float v = (*in) * AMDTP_FLOAT_MULTIPLIER; 
     953                unsigned int tmp = ((int) v); 
     954                tmp = ( tmp & 0x00FFFFFF ) | 0x40000000; 
     955                *target_event = CondSwapToBus32((quadlet_t)tmp); 
    943956#endif 
    944                 float v = (*in) * AMDTP_FLOAT_MULTIPLIER; 
    945                 unsigned int tmp = ((int) lrintf(v)); 
    946  
    947                 tmp = ( tmp >> 8 ) | 0x40000000; 
    948                 *target_event = CondSwapToBus32((quadlet_t)tmp); 
    949957                buffer++; 
    950958                target_event += m_dimension; 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h

    r1348 r1498  
    105105    virtual unsigned int getMaxPacketSize() 
    106106                    {return 4 * (2 + getSytInterval() * m_dimension);}; 
    107     virtual unsigned int getAveragePacketSize(); 
    108107    virtual unsigned int getEventsPerFrame() 
    109108                    { return m_dimension; }; 
  • trunk/libffado/src/libstreaming/generic/Port.cpp

    r904 r1498  
    126126Port::enable()  { 
    127127    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Enabling port %s...\n",m_Name.c_str()); 
    128     m_disabled=false; 
     128    m_disabled = false; 
    129129} 
    130130 
     
    133133Port::disable() { 
    134134    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Disabling port %s...\n",m_Name.c_str()); 
    135     m_disabled=false; 
     135    m_disabled = true; 
     136
     137 
     138 
     139/** 
     140 * Obtain the port type in string format 
     141 * @return type name of the port 
     142 */ 
     143std::string 
     144Port::getPortTypeName() 
     145
     146    switch(m_PortType) { 
     147        case E_Audio: 
     148            return "Audio"; 
     149        case E_Midi: 
     150            return "MIDI"; 
     151        case E_Control: 
     152            return "Control"; 
     153        default: 
     154            return "Invalid"; 
     155    } 
    136156} 
    137157 
    138158void Port::show() { 
    139159    debugOutput(DEBUG_LEVEL_VERBOSE,"Name          : %s\n", m_Name.c_str()); 
    140     debugOutput(DEBUG_LEVEL_VERBOSE,"Enabled?      : %d\n", m_disabled); 
     160    debugOutput(DEBUG_LEVEL_VERBOSE,"Enabled?      : %d\n", m_disabled==false); 
    141161    debugOutput(DEBUG_LEVEL_VERBOSE,"State?        : %d\n", m_State); 
    142162    debugOutput(DEBUG_LEVEL_VERBOSE,"Buffer Size   : %d\n", m_buffersize); 
  • trunk/libffado/src/libstreaming/generic/Port.h

    r864 r1498  
    105105 
    106106    enum E_PortType getPortType() {return m_PortType;}; ///< returns the port type (is fixed) 
     107    std::string getPortTypeName(); 
    107108    enum E_Direction getDirection() {return m_Direction;}; ///< returns the direction (is fixed) 
    108109 
  • trunk/libffado/src/libstreaming/generic/PortManager.cpp

    r876 r1498  
    3535IMPL_DEBUG_MODULE( PortManager, PortManager, DEBUG_LEVEL_NORMAL ); 
    3636 
    37 PortManager::PortManager() { 
    38 
    39  
    40 PortManager::~PortManager() { 
     37PortManager::PortManager() 
     38
     39
     40 
     41PortManager::~PortManager() 
     42
    4143    flushDebugOutput(); 
    4244    // delete all ports that are still registered to the manager 
     
    4648      delete m_Ports.front(); 
    4749    } 
    48 
    49  
    50 bool PortManager::makeNameUnique(Port *port) 
    51 
    52     bool done=false; 
    53     int idx=0; 
    54     std::string portname_orig=port->getName(); 
    55      
    56     while(!done && idx<10000) { 
     50    for ( Util::FunctorVectorIterator it = m_UpdateHandlers.begin(); 
     51          it != m_UpdateHandlers.end(); 
     52          ++it ) 
     53    { 
     54        Util::Functor* func = *it; 
     55        delete func; 
     56    } 
     57
     58 
     59bool 
     60PortManager::makeNameUnique(Port *port) 
     61
     62    bool done = false; 
     63    int idx = 0; 
     64    std::string portname_orig = port->getName(); 
     65 
     66    while(!done && idx < 10000) { 
    5767        bool is_unique=true; 
    58          
     68 
    5969        for ( PortVectorIterator it = m_Ports.begin(); 
    6070        it != m_Ports.end(); 
     
    6373            is_unique &= !((*it)->getName() == port->getName()); 
    6474        } 
    65          
     75 
    6676        if (is_unique) { 
    67             done=true; 
     77            done = true; 
    6878        } else { 
    6979            std::ostringstream portname; 
    7080            portname << portname_orig << idx++; 
    71              
    7281            port->setName(portname.str()); 
    7382        } 
    7483    } 
    75      
    76     if(idx<10000) return true; 
     84 
     85    if(idx < 10000) return true; 
    7786    else return false; 
    7887} 
     
    8392 * @return 
    8493 */ 
    85 bool PortManager::registerPort(Port *port) 
     94bool 
     95PortManager::registerPort(Port *port) 
    8696{ 
    8797    assert(port); 
     
    94104    if (makeNameUnique(port)) { 
    95105        m_Ports.push_back(port); 
     106        callUpdateHandlers(); 
    96107        return true; 
    97108    } else { 
     
    100111} 
    101112 
    102 bool PortManager::unregisterPort(Port *port) 
     113bool 
     114PortManager::unregisterPort(Port *port) 
    103115{ 
    104116    assert(port); 
     
    111123        if(*it == port) { 
    112124            m_Ports.erase(it); 
     125            callUpdateHandlers(); 
    113126            return true; 
    114127        } 
     
    118131 
    119132    return false; //not found 
    120  
    121 
    122  
    123 int PortManager::getPortCount(enum Port::E_PortType type) { 
     133
     134 
     135int 
     136PortManager::getPortCount(enum Port::E_PortType type) 
     137
    124138    int count=0; 
    125139 
     
    135149} 
    136150 
    137 int PortManager::getPortCount() { 
    138     int count=0; 
    139  
    140     count+=m_Ports.size(); 
     151int 
     152PortManager::getPortCount() 
     153
     154    int count = 0; 
     155 
     156    count += m_Ports.size(); 
    141157 
    142158    return count; 
    143159} 
    144160 
    145 Port * PortManager::getPortAtIdx(unsigned int index) { 
     161Port * 
     162PortManager::getPortAtIdx(unsigned int index) 
     163
    146164 
    147165    return m_Ports.at(index); 
     
    149167} 
    150168 
    151 void PortManager::setVerboseLevel(int i) { 
     169void 
     170PortManager::setVerboseLevel(int i) 
     171
    152172    setDebugLevel(i); 
    153173    for ( PortVectorIterator it = m_Ports.begin(); 
     
    160180 
    161181 
    162 bool PortManager::resetPorts() { 
     182bool 
     183PortManager::resetPorts() 
     184
    163185    debugOutput( DEBUG_LEVEL_VERBOSE, "reset ports\n"); 
    164186 
     
    175197} 
    176198 
    177 bool PortManager::initPorts() { 
     199bool 
     200PortManager::initPorts() 
     201
    178202    debugOutput( DEBUG_LEVEL_VERBOSE, "init ports\n"); 
    179203 
     
    190214} 
    191215 
    192 bool PortManager::preparePorts() { 
     216bool 
     217PortManager::preparePorts() 
     218
    193219    debugOutput( DEBUG_LEVEL_VERBOSE, "preparing ports\n"); 
    194220 
     
    201227            return false; 
    202228        } 
    203  
    204     } 
    205     return true; 
    206 
    207  
    208 
     229    } 
     230    return true; 
     231
     232 
     233bool 
     234PortManager::addPortManagerUpdateHandler( Util::Functor* functor ) 
     235
     236    debugOutput(DEBUG_LEVEL_VERBOSE, "Adding PortManagerUpdate handler (%p)\n", functor); 
     237    m_UpdateHandlers.push_back( functor ); 
     238    return true; 
     239
     240 
     241bool 
     242PortManager::remPortManagerUpdateHandler( Util::Functor* functor ) 
     243
     244    debugOutput(DEBUG_LEVEL_VERBOSE, "Removing PortManagerUpdate handler (%p)\n", functor); 
     245 
     246    for ( Util::FunctorVectorIterator it = m_UpdateHandlers.begin(); 
     247          it != m_UpdateHandlers.end(); 
     248          ++it ) 
     249    { 
     250        if ( *it == functor ) { 
     251            debugOutput(DEBUG_LEVEL_VERBOSE, " found\n"); 
     252            m_UpdateHandlers.erase( it ); 
     253            return true; 
     254        } 
     255    } 
     256    debugOutput(DEBUG_LEVEL_VERBOSE, " not found\n"); 
     257    return false; 
     258
     259 
     260Util::Functor* 
     261PortManager::getUpdateHandlerForPtr(void *ptr) 
     262
     263    for ( Util::FunctorVectorIterator it = m_UpdateHandlers.begin(); 
     264          it != m_UpdateHandlers.end(); 
     265          ++it ) 
     266    { 
     267        if ( (*it)->matchCallee(ptr) ) { 
     268            debugOutput(DEBUG_LEVEL_VERBOSE, " found\n"); 
     269            return *it; 
     270        } 
     271    } 
     272    return NULL; 
     273
     274 
     275void 
     276PortManager::callUpdateHandlers() 
     277
     278    for ( Util::FunctorVectorIterator it = m_UpdateHandlers.begin(); 
     279          it != m_UpdateHandlers.end(); 
     280          ++it ) 
     281    { 
     282        Util::Functor* func = *it; 
     283        debugOutput(DEBUG_LEVEL_VERBOSE, "Calling PortManagerUpdate handler (%p)\n", func); 
     284        ( *func )(); 
     285    } 
     286
     287 
     288
  • trunk/libffado/src/libstreaming/generic/PortManager.h

    r864 r1498  
    2727#include "Port.h" 
    2828 
     29#include "libutil/Functors.h" 
    2930#include "debugmodule/debugmodule.h" 
    3031 
     
    6162    virtual bool preparePorts(); 
    6263 
    63      virtual void setVerboseLevel(int l); 
     64    virtual void setVerboseLevel(int l); 
     65 
     66    bool addPortManagerUpdateHandler( Util::Functor* functor ); 
     67    bool remPortManagerUpdateHandler( Util::Functor* functor ); 
     68    Util::Functor* getUpdateHandlerForPtr(void *ptr); // ugly!! 
    6469 
    6570protected: 
     71    void callUpdateHandlers(); 
    6672    PortVector m_Ports; 
    6773 
     74    Util::FunctorVector m_UpdateHandlers; 
    6875    DECLARE_DEBUG_MODULE; 
    6976}; 
  • trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp

    r1348 r1498  
    413413            int64_t last_timestamp_fixed; 
    414414            // first try to add one second 
    415             last_timestamp_fixed = m_last_timestamp + TICKS_PER_SECOND
     415            last_timestamp_fixed = addTicks(m_last_timestamp, TICKS_PER_SECOND)
    416416            diff = diffTicks(last_timestamp_fixed, m_last_timestamp2); 
    417417            if(diff-ticks_per_packet < 50 && diff-ticks_per_packet > -50) { 
     
    421421                debugWarning("HACK: fixed by adding one second of ticks. This is a bug being run-time fixed.\n"); 
    422422                m_last_timestamp = last_timestamp_fixed; 
    423             } 
    424             // then try to subtract one second 
    425             last_timestamp_fixed = m_last_timestamp - TICKS_PER_SECOND; 
    426             if(last_timestamp_fixed >= 0) { 
     423            } else { 
     424                // if that didn't work, try to subtract one second 
     425                last_timestamp_fixed = substractTicks(m_last_timestamp, TICKS_PER_SECOND); 
    427426                diff = diffTicks(last_timestamp_fixed, m_last_timestamp2); 
    428427                if(diff-ticks_per_packet < 50 && diff-ticks_per_packet > -50) { 
  • trunk/libffado/src/libstreaming/generic/StreamProcessor.h

    r1348 r1498  
    290290    virtual unsigned int getPacketsPerPeriod(); 
    291291    virtual unsigned int getMaxPacketSize() = 0; 
    292     virtual unsigned int getAveragePacketSize() = 0; 
    293292private: 
    294293    int m_channel; 
  • trunk/libffado/src/libstreaming/motu/MotuReceiveStreamProcessor.cpp

    r1361 r1498  
    9696 
    9797unsigned int 
    98 MotuReceiveStreamProcessor::getAveragePacketSize() 
    99 { 
    100     // in one second we have 8000 packets 
    101     // containing FRAMERATE frames 
    102     // so on average bytes/packet: (8000 packet headers + FRAMERATE * frame_size) / 8000 
    103     #warning FIXME 
    104     int framerate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate(); 
    105     return framerate<=48000?616:(framerate<=96000?1032:1160); 
    106 } 
    107  
    108 unsigned int 
    10998MotuReceiveStreamProcessor::getNominalFramesPerPacket() { 
    11099    int framerate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate(); 
     
    235224        case Port::E_Audio: 
    236225            if(decodeMotuEventsToPort(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
    237                 debugWarning("Could not decode packet data to port %s",(*it)->getName().c_str()); 
     226                debugWarning("Could not decode packet data to port %s\n",(*it)->getName().c_str()); 
    238227                no_problem=false; 
    239228            } 
     
    241230        case Port::E_Midi: 
    242231             if(decodeMotuMidiEventsToPort(static_cast<MotuMidiPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
    243                  debugWarning("Could not decode packet midi data to port %s",(*it)->getName().c_str()); 
     232                 debugWarning("Could not decode packet midi data to port %s\n",(*it)->getName().c_str()); 
    244233                 no_problem=false; 
    245234             } 
     
    284273                    *buffer = (*src_data<<16)+(*(src_data+1)<<8)+*(src_data+2); 
    285274                    // Sign-extend highest bit of 24-bit int. 
    286                     // FIXME: this isn't strictly needed since E_Int24 is a 24-bit, 
     275                    // This isn't strictly needed since E_Int24 is a 24-bit, 
    287276                    // but doing so shouldn't break anything and makes the data 
    288277                    // easier to deal with during debugging. 
  • trunk/libffado/src/libstreaming/motu/MotuReceiveStreamProcessor.h

    r1348 r1498  
    152152                {return m_event_size;}; 
    153153    virtual unsigned int getMaxPacketSize(); 
    154     virtual unsigned int getAveragePacketSize(); 
    155154    virtual unsigned int getEventsPerFrame()  
    156                     { return 1; }; // FIXME: check 
     155                    { return 1; }; 
    157156    virtual unsigned int getNominalFramesPerPacket(); 
    158157 
  • trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp

    r1361 r1498  
    9191 
    9292unsigned int 
    93 MotuTransmitStreamProcessor::getAveragePacketSize() 
    94 { 
    95     // in one second we have 8000 packets 
    96     // containing FRAMERATE frames 
    97     // so on average bytes/packet: (8000 packet headers + FRAMERATE * frame_size) / 8000 
    98     #warning FIXME 
    99     int framerate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate(); 
    100     return framerate<=48000?616:(framerate<=96000?1032:1160); 
    101 } 
    102  
    103 unsigned int 
    10493MotuTransmitStreamProcessor::getNominalFramesPerPacket() { 
    10594    int framerate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate(); 
     
    481470{ 
    482471    quadlet_t *quadlet = (quadlet_t *)data; 
    483     // Size of a single data frame in quadlets.  For data sent by the 
     472    // Size of a single data frame in quadlets.  For data sent TO the 
    484473    // Ultralite this is not strictly true (with m_event_size 52, dbs is set 
    485     // to 19).  Even so, we'll run with the assumption that a different dbs 
    486     // will be fine unless proven otherwise. 
     474    // to 13, even though data sent by the Ultralite uses 19 as one would 
     475    // expect from a 52-byte event).  Even so, we'll run with the assumption 
     476    // that a different dbs will be fine unless proven otherwise. 
    487477    unsigned dbs = m_event_size / 4; 
    488478 
     
    545535      it != m_Ports.end(); 
    546536      ++it ) { 
    547         // If this port is disabled, don't process it 
    548         if((*it)->isDisabled()) {continue;}; 
     537        // If this port is disabled, unconditionally send it silence. 
     538        if((*it)->isDisabled()) { 
     539          if (encodeSilencePortToMotuEvents(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
     540            debugWarning("Could not encode silence for disabled port %s to Motu events\n",(*it)->getName().c_str()); 
     541            // Don't treat this as a fatal error at this point 
     542          } 
     543          continue; 
     544        } 
    549545 
    550546        Port *port=(*it); 
     
    554550        case Port::E_Audio: 
    555551            if (encodePortToMotuEvents(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
    556                 debugWarning("Could not encode port %s to Motu events",(*it)->getName().c_str()); 
     552                debugWarning("Could not encode port %s to Motu events\n",(*it)->getName().c_str()); 
    557553                no_problem=false; 
    558554            } 
     
    560556        case Port::E_Midi: 
    561557             if (encodePortToMotuMidiEvents(static_cast<MotuMidiPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
    562                  debugWarning("Could not encode port %s to Midi events",(*it)->getName().c_str()); 
     558                 debugWarning("Could not encode port %s to Midi events\n",(*it)->getName().c_str()); 
    563559                 no_problem=false; 
    564560             } 
     
    586582        case Port::E_Audio: 
    587583            if (encodeSilencePortToMotuEvents(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
    588                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str()); 
     584                debugWarning("Could not encode port %s to MBLA events\n",(*it)->getName().c_str()); 
    589585                no_problem = false; 
    590586            } 
     
    592588        case Port::E_Midi: 
    593589            if (encodeSilencePortToMotuMidiEvents(static_cast<MotuMidiPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
    594                 debugWarning("Could not encode port %s to Midi events",(*it)->getName().c_str()); 
     590                debugWarning("Could not encode port %s to Midi events\n",(*it)->getName().c_str()); 
    595591                no_problem = false; 
    596592            } 
     
    727723            mb_head &= MIDIBUFFER_SIZE-1; 
    728724            if (unlikely(mb_head == mb_tail)) { 
    729             /* Buffer overflow - dump oldest byte */ 
    730             /* FIXME: ideally this would dump an entire MIDI message, but this is only 
     725            /* Buffer overflow - dump oldest byte. */ 
     726            /* Ideally this would dump an entire MIDI message, but this is only 
    731727             * feasible if it's possible to determine the message size easily. 
    732728             */ 
  • trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.h

    r1348 r1498  
    7676                {return m_event_size;}; 
    7777    virtual unsigned int getMaxPacketSize(); 
    78     virtual unsigned int getAveragePacketSize(); 
    7978    virtual unsigned int getEventsPerFrame()  
    80                     { return 1; }; // FIXME: check 
     79                    { return 1; }; 
    8180    virtual unsigned int getNominalFramesPerPacket(); 
    8281 
  • trunk/libffado/src/libstreaming/StreamProcessorManager.cpp

    r1348 r1498  
    4646    , m_parent( p ) 
    4747    , m_xrun_happened( false ) 
    48     , m_activity_wait_timeout_usec( 1000*1000 ) 
     48    , m_activity_wait_timeout_nsec( 0 ) // dynamically set 
    4949    , m_nb_buffers( 0 ) 
    5050    , m_period( 0 ) 
     
    6666    , m_parent( p ) 
    6767    , m_xrun_happened( false ) 
    68     , m_activity_wait_timeout_usec( 1000*1000 ) 
     68    , m_activity_wait_timeout_nsec( 0 ) // dynamically set 
    6969    , m_nb_buffers(nb_buffers) 
    7070    , m_period(period) 
     
    150150    int result; 
    151151 
    152     long long int timeout_nsec=0; 
    153     if (m_activity_wait_timeout_usec >= 0) { 
    154         timeout_nsec = m_activity_wait_timeout_usec * 1000LL; 
     152    if (m_activity_wait_timeout_nsec >= 0) { 
    155153 
    156154        if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { 
     
    158156            return eAR_Error; 
    159157        } 
    160         ts.tv_nsec += timeout_nsec; 
     158        ts.tv_nsec += m_activity_wait_timeout_nsec; 
    161159        while(ts.tv_nsec >= 1000000000LL) { 
    162160            ts.tv_sec += 1; 
     
    165163    } 
    166164 
    167     if (m_activity_wait_timeout_usec >= 0) { 
     165    if (m_activity_wait_timeout_nsec >= 0) { 
    168166        result = sem_timedwait(&m_activity_semaphore, &ts); 
    169167    } else { 
     
    186184                        this, result); 
    187185            debugError("(%p) timeout_nsec=%lld ts.sec=%d ts.nsec=%lld\n",  
    188                        this, timeout_nsec, ts.tv_sec, ts.tv_nsec); 
     186                       this, m_activity_wait_timeout_nsec, ts.tv_sec, ts.tv_nsec); 
    189187            return eAR_Error; 
    190188        } else { 
     
    192190                        this, result, errno); 
    193191            debugError("(%p) timeout_nsec=%lld ts.sec=%d ts.nsec=%lld\n",  
    194                        this, timeout_nsec, ts.tv_sec, ts.tv_nsec); 
     192                       this, m_activity_wait_timeout_nsec, ts.tv_sec, ts.tv_nsec); 
    195193            return eAR_Error; 
    196194        } 
     
    219217        processor->setVerboseLevel(getDebugLevel()); // inherit debug level 
    220218        m_ReceiveProcessors.push_back(processor); 
     219        Util::Functor* f = new Util::MemberFunctor0< StreamProcessorManager*, void (StreamProcessorManager::*)() > 
     220                    ( this, &StreamProcessorManager::updateShadowLists, false ); 
     221        processor->addPortManagerUpdateHandler(f); 
     222        updateShadowLists(); 
    221223        return true; 
    222224    } 
    223  
    224225    if (processor->getType() == StreamProcessor::ePT_Transmit) { 
    225226        processor->setVerboseLevel(getDebugLevel()); // inherit debug level 
    226227        m_TransmitProcessors.push_back(processor); 
     228        Util::Functor* f = new Util::MemberFunctor0< StreamProcessorManager*, void (StreamProcessorManager::*)() > 
     229                    ( this, &StreamProcessorManager::updateShadowLists, false ); 
     230        processor->addPortManagerUpdateHandler(f); 
     231        updateShadowLists(); 
    227232        return true; 
    228233    } 
     
    249254                } 
    250255                m_ReceiveProcessors.erase(it); 
     256                // remove the functor 
     257                Util::Functor * f = processor->getUpdateHandlerForPtr(this); 
     258                if(f) { 
     259                    processor->remPortManagerUpdateHandler(f); 
     260                    delete f; 
     261                } 
     262                updateShadowLists(); 
    251263                return true; 
    252264            } 
     
    265277                } 
    266278                m_TransmitProcessors.erase(it); 
     279                // remove the functor 
     280                Util::Functor * f = processor->getUpdateHandlerForPtr(this); 
     281                if(f) { 
     282                    processor->remPortManagerUpdateHandler(f); 
     283                    delete f; 
     284                } 
     285                updateShadowLists(); 
    267286                return true; 
    268287            } 
     
    276295bool StreamProcessorManager::setSyncSource(StreamProcessor *s) { 
    277296    debugOutput( DEBUG_LEVEL_VERBOSE, "Setting sync source to (%p)\n", s); 
    278     m_SyncSource=s; 
     297    m_SyncSource = s; 
    279298    return true; 
    280299} 
     
    356375    debugOutput(DEBUG_LEVEL_VERBOSE, "setting activity timeout to %d\n", timeout_usec); 
    357376    setActivityWaitTimeoutUsec(timeout_usec); 
     377 
     378    updateShadowLists(); 
    358379 
    359380    return true; 
     
    440461bool StreamProcessorManager::syncStartAll() { 
    441462    if(m_SyncSource == NULL) return false; 
     463 
     464    // get the options 
     465    int signal_delay_ticks = STREAMPROCESSORMANAGER_SIGNAL_DELAY_TICKS; 
     466    int sync_wait_time_msec = STREAMPROCESSORMANAGER_SYNC_WAIT_TIME_MSEC; 
     467    int cycles_for_startup = STREAMPROCESSORMANAGER_CYCLES_FOR_STARTUP; 
     468    int prestart_cycles_for_xmit = STREAMPROCESSORMANAGER_PRESTART_CYCLES_FOR_XMIT; 
     469    int prestart_cycles_for_recv = STREAMPROCESSORMANAGER_PRESTART_CYCLES_FOR_RECV; 
     470    Util::Configuration &config = m_parent.getConfiguration(); 
     471    config.getValueForSetting("streaming.spm.signal_delay_ticks", signal_delay_ticks); 
     472    config.getValueForSetting("streaming.spm.sync_wait_time_msec", sync_wait_time_msec); 
     473    config.getValueForSetting("streaming.spm.cycles_for_startup", cycles_for_startup); 
     474    config.getValueForSetting("streaming.spm.prestart_cycles_for_xmit", prestart_cycles_for_xmit); 
     475    config.getValueForSetting("streaming.spm.prestart_cycles_for_recv", prestart_cycles_for_recv); 
     476 
    442477    // figure out when to get the SP's running. 
    443478    // the xmit SP's should also know the base timestamp 
     
    461496    // time to a later time instant also causes the xmit buffer fill to be 
    462497    // lower on average. 
    463     max_of_min_delay += STREAMPROCESSORMANAGER_SIGNAL_DELAY_TICKS
     498    max_of_min_delay += signal_delay_ticks
    464499 
    465500    m_SyncSource->setSyncDelay(max_of_min_delay); 
     
    480515    debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for sync...\n"); 
    481516 
    482     unsigned int nb_sync_runs = (STREAMPROCESSORMANAGER_SYNC_WAIT_TIME_MSEC * getNominalRate()); 
     517    unsigned int nb_sync_runs = (sync_wait_time_msec * getNominalRate()); 
    483518    nb_sync_runs /= 1000; 
    484519    nb_sync_runs /= getPeriodSize(); 
     
    513548    // can start wet-running correctly. 
    514549    time_of_first_sample = addTicks(time_of_first_sample, 
    515                                     STREAMPROCESSORMANAGER_CYCLES_FOR_STARTUP * TICKS_PER_CYCLE); 
     550                                    cycles_for_startup * TICKS_PER_CYCLE); 
    516551 
    517552    debugOutput( DEBUG_LEVEL_VERBOSE, "  => first sample at TS=%011llu (%03us %04uc %04ut)...\n",  
     
    524559    // such that we know it is wet-running when it should output its first sample 
    525560    uint64_t time_to_start_xmit = substractTicks(time_of_first_sample,  
    526                                                  STREAMPROCESSORMANAGER_PRESTART_CYCLES_FOR_XMIT * TICKS_PER_CYCLE); 
     561                                                 prestart_cycles_for_xmit * TICKS_PER_CYCLE); 
    527562 
    528563    uint64_t time_to_start_recv = substractTicks(time_of_first_sample, 
    529                                                  STREAMPROCESSORMANAGER_PRESTART_CYCLES_FOR_RECV * TICKS_PER_CYCLE); 
     564                                                 prestart_cycles_for_recv * TICKS_PER_CYCLE); 
    530565    debugOutput( DEBUG_LEVEL_VERBOSE, "  => xmit starts at  TS=%011llu (%03us %04uc %04ut)...\n",  
    531566        time_to_start_xmit, 
     
    586621    // note: the SP's are scheduled to start in STREAMPROCESSORMANAGER_CYCLES_FOR_STARTUP cycles, 
    587622    // so a 20 times this value should be a good timeout 
    588     int cnt = STREAMPROCESSORMANAGER_CYCLES_FOR_STARTUP * 20; // by then it should have started 
     623    int cnt = cycles_for_startup * 20; // by then it should have started 
    589624    while (!m_SyncSource->isRunning() && cnt) { 
    590625        SleepRelativeUsec(125); 
     
    650685    unsigned int i; 
    651686 
    652     unsigned int periods_per_align_try = (STREAMPROCESSORMANAGER_ALIGN_AVERAGE_TIME_MSEC * getNominalRate()); 
     687    int cnt = STREAMPROCESSORMANAGER_NB_ALIGN_TRIES; 
     688    int align_average_time_msec = STREAMPROCESSORMANAGER_ALIGN_AVERAGE_TIME_MSEC; 
     689    Util::Configuration &config = m_parent.getConfiguration(); 
     690    config.getValueForSetting("streaming.spm.align_tries", cnt); 
     691    config.getValueForSetting("streaming.spm.align_average_time_msec", align_average_time_msec); 
     692 
     693    unsigned int periods_per_align_try = (align_average_time_msec * getNominalRate()); 
    653694    periods_per_align_try /= 1000; 
    654695    periods_per_align_try /= getPeriodSize(); 
     
    656697 
    657698    bool aligned = false; 
    658     int cnt = STREAMPROCESSORMANAGER_NB_ALIGN_TRIES; 
    659699    while (!aligned && cnt--) { 
    660700        nb_sync_runs = periods_per_align_try; 
     
    13011341    debugOutputShort( DEBUG_LEVEL_NORMAL, "----------------------------------------------------\n"); 
    13021342 
     1343    // list port info in verbose mode 
     1344    debugOutputShort( DEBUG_LEVEL_VERBOSE, "Port Information\n"); 
     1345    int nb_ports; 
     1346     
     1347    debugOutputShort( DEBUG_LEVEL_VERBOSE, " Playback\n"); 
     1348    nb_ports = getPortCount(Port::E_Playback); 
     1349    for(int i=0; i < nb_ports; i++) { 
     1350        Port *p = getPortByIndex(i, Port::E_Playback); 
     1351        debugOutputShort( DEBUG_LEVEL_VERBOSE, "  %3d (%p): ", i, p); 
     1352        if (p) { 
     1353            bool disabled = p->isDisabled(); 
     1354            debugOutputShort( DEBUG_LEVEL_VERBOSE, "[%p] [%3s] ", &p->getManager(), (disabled?"off":"on")); 
     1355            debugOutputShort( DEBUG_LEVEL_VERBOSE, "[%7s] ", p->getPortTypeName().c_str()); 
     1356            debugOutputShort( DEBUG_LEVEL_VERBOSE, "%3s ", p->getName().c_str()); 
     1357        } else { 
     1358            debugOutputShort( DEBUG_LEVEL_VERBOSE, "invalid "); 
     1359        } 
     1360        debugOutputShort( DEBUG_LEVEL_VERBOSE, "\n"); 
     1361    } 
     1362    debugOutputShort( DEBUG_LEVEL_VERBOSE, " Capture\n"); 
     1363    nb_ports = getPortCount(Port::E_Capture); 
     1364    for(int i=0; i < nb_ports; i++) { 
     1365        Port *p = getPortByIndex(i, Port::E_Capture); 
     1366        debugOutputShort( DEBUG_LEVEL_VERBOSE, "  %3d (%p): ", i, p); 
     1367        if (p) { 
     1368            bool disabled = p->isDisabled(); 
     1369            debugOutputShort( DEBUG_LEVEL_VERBOSE, "[%p] [%3s] ", &p->getManager(), (disabled?"off":"on")); 
     1370            debugOutputShort( DEBUG_LEVEL_VERBOSE, "[%7s] ", p->getPortTypeName().c_str()); 
     1371            debugOutputShort( DEBUG_LEVEL_VERBOSE, " %3s ", p->getName().c_str()); 
     1372        } else { 
     1373            debugOutputShort( DEBUG_LEVEL_VERBOSE, " invalid "); 
     1374        } 
     1375        debugOutputShort( DEBUG_LEVEL_VERBOSE, "\n"); 
     1376    } 
     1377 
     1378    debugOutputShort( DEBUG_LEVEL_VERBOSE, "----------------------------------------------------\n"); 
     1379 
    13031380} 
    13041381 
     
    13581435} 
    13591436 
    1360 // TODO: implement a port map here, instead of the loop 
     1437void 
     1438StreamProcessorManager::updateShadowLists() 
     1439
     1440    debugOutput( DEBUG_LEVEL_VERBOSE, "Updating port shadow lists...\n"); 
     1441    m_CapturePorts_shadow.clear(); 
     1442    m_PlaybackPorts_shadow.clear(); 
     1443 
     1444    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     1445        it != m_ReceiveProcessors.end(); 
     1446        ++it ) { 
     1447        PortManager *pm = *it; 
     1448        for (int i=0; i < pm->getPortCount(); i++) { 
     1449            Port *p = pm->getPortAtIdx(i); 
     1450            if (!p) { 
     1451                debugError("getPortAtIdx(%d) returned NULL\n", i); 
     1452                continue; 
     1453            } 
     1454            if(p->getDirection() != Port::E_Capture) { 
     1455                debugError("port at idx %d for receive SP is not a capture port!\n", i); 
     1456                continue; 
     1457            } 
     1458            m_CapturePorts_shadow.push_back(p); 
     1459        } 
     1460    } 
     1461    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     1462        it != m_TransmitProcessors.end(); 
     1463        ++it ) { 
     1464        PortManager *pm = *it; 
     1465        for (int i=0; i < pm->getPortCount(); i++) { 
     1466            Port *p = pm->getPortAtIdx(i); 
     1467            if (!p) { 
     1468                debugError("getPortAtIdx(%d) returned NULL\n", i); 
     1469                continue; 
     1470            } 
     1471            if(p->getDirection() != Port::E_Playback) { 
     1472                debugError("port at idx %d for transmit SP is not a playback port!\n", i); 
     1473                continue; 
     1474            } 
     1475            m_PlaybackPorts_shadow.push_back(p); 
     1476        } 
     1477    } 
     1478
     1479 
    13611480Port* StreamProcessorManager::getPortByIndex(int idx, enum Port::E_Direction direction) { 
    1362     int count=0; 
    1363     int prevcount=0; 
    1364  
     1481    debugOutputExtreme( DEBUG_LEVEL_ULTRA_VERBOSE, "getPortByIndex(%d, %d)...\n", idx, direction); 
    13651482    if (direction == Port::E_Capture) { 
    1366         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    1367             it != m_ReceiveProcessors.end(); 
    1368             ++it ) { 
    1369             count += (*it)->getPortCount(); 
    1370             if (count > idx) { 
    1371                 return (*it)->getPortAtIdx(idx-prevcount); 
    1372             } 
    1373             prevcount=count; 
    1374         } 
     1483        #ifdef DEBUG 
     1484        if(idx >= (int)m_CapturePorts_shadow.size()) { 
     1485            debugError("Capture port %d out of range (%d)\n", idx, m_CapturePorts_shadow.size()); 
     1486            return NULL; 
     1487        } 
     1488        #endif 
     1489        return m_CapturePorts_shadow.at(idx); 
    13751490    } else { 
    1376         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    1377             it != m_TransmitProcessors.end(); 
    1378             ++it ) { 
    1379             count += (*it)->getPortCount(); 
    1380             if (count > idx) { 
    1381                 return (*it)->getPortAtIdx(idx-prevcount); 
    1382             } 
    1383             prevcount=count; 
    1384         } 
     1491        #ifdef DEBUG 
     1492        if(idx >= (int)m_PlaybackPorts_shadow.size()) { 
     1493            debugError("Playback port %d out of range (%d)\n", idx, m_PlaybackPorts_shadow.size()); 
     1494            return NULL; 
     1495        } 
     1496        #endif 
     1497        return m_PlaybackPorts_shadow.at(idx); 
    13851498    } 
    13861499    return NULL; 
  • trunk/libffado/src/libstreaming/StreamProcessorManager.h

    r1336 r1498  
    2525#define __FFADO_STREAMPROCESSORMANAGER__ 
    2626 
     27#include "generic/PortManager.h" 
    2728#include "generic/Port.h" 
    2829#include "generic/StreamProcessor.h" 
     
    102103    // timeout occurs. 
    103104    void setActivityWaitTimeoutUsec(int usec) 
    104             {m_activity_wait_timeout_usec = usec;}; 
     105            {m_activity_wait_timeout_nsec = usec*1000LL;}; 
    105106    int getActivityWaitTimeoutUsec()  
    106             {return m_activity_wait_timeout_usec;}; 
     107            {return m_activity_wait_timeout_nsec/1000;}; 
    107108 
    108109    int getPortCount(enum Port::E_PortType, enum Port::E_Direction); 
     
    168169    // thread related vars 
    169170    bool m_xrun_happened; 
    170     int m_activity_wait_timeout_usec; 
     171    int64_t m_activity_wait_timeout_nsec; 
    171172    bool m_thread_realtime; 
    172173    int m_thread_priority; 
     
    178179    StreamProcessorVector m_ReceiveProcessors; 
    179180    StreamProcessorVector m_TransmitProcessors; 
     181 
     182    // port shadow lists 
     183    PortVector m_CapturePorts_shadow; 
     184    PortVector m_PlaybackPorts_shadow; 
     185    void updateShadowLists(); 
    180186 
    181187    unsigned int m_nb_buffers; 
  • trunk/libffado/src/libutil/ByteSwap.h

    r1254 r1498  
    155155#ifdef __SSE2__ 
    156156#include <emmintrin.h> 
    157 #warning SSE2 build 
    158  
    159 static 
    160 //inline void 
    161 void 
     157 
     158static inline void 
    162159byteSwapToBus(quadlet_t *data, unsigned int nb_elements) 
    163160{ 
     
    207204} 
    208205 
    209 static 
    210 //inline void 
    211 void 
     206static inline void 
    212207byteSwapFromBus(quadlet_t *data, unsigned int nb_elements) 
    213208{ 
  • trunk/libffado/src/libutil/cmd_serialize.cpp

    r1234 r1498  
    4444CoutSerializer::write( byte_t d, const char* name ) 
    4545{ 
    46     debugOutput( DEBUG_LEVEL_NORMAL, "  %3d:        0x%02x %-40.40s\n", m_cnt, d, name ); 
     46    debugOutput( DEBUG_LEVEL_NORMAL, "  %3d:        0x%02x %-60.60s\n", m_cnt, d, name ); 
    4747    m_cnt += sizeof( byte_t ); 
    4848 
     
    5353CoutSerializer::write( uint16_t d, const char* name ) 
    5454{ 
    55     debugOutput( DEBUG_LEVEL_NORMAL, "  %3d:    0x%04x %-40.40s\n", m_cnt, d, name ); 
     55    debugOutput( DEBUG_LEVEL_NORMAL, "  %3d:    0x%04x %-60.60s\n", m_cnt, d, name ); 
    5656    m_cnt += sizeof( uint16_t ); 
    5757 
     
    6262CoutSerializer::write( quadlet_t d, const char* name ) 
    6363{ 
    64     debugOutput( DEBUG_LEVEL_NORMAL, "  %3d: 0x%08x %-40.40s\n", m_cnt, d, name ); 
     64    debugOutput( DEBUG_LEVEL_NORMAL, "  %3d: 0x%08x %-60.60s\n", m_cnt, d, name ); 
    6565    m_cnt += sizeof( quadlet_t ); 
    6666    return true; 
     
    7070CoutSerializer::write( const char * v, size_t len, const char* name ) 
    7171{ 
    72     debugOutput( DEBUG_LEVEL_NORMAL, "  %3d: %s %-40.40s\n", m_cnt, v, name ); 
     72    debugOutput( DEBUG_LEVEL_NORMAL, "  %3d: %s %-60.60s\n", m_cnt, v, name ); 
    7373    m_cnt += len; 
    7474    return true; 
  • trunk/libffado/src/libutil/Configuration.cpp

    r1336 r1498  
    2929namespace Util { 
    3030 
    31 IMPL_DEBUG_MODULE( Configuration, Configuration, DEBUG_LEVEL_VERBOSE ); 
     31IMPL_DEBUG_MODULE( Configuration, Configuration, DEBUG_LEVEL_NORMAL ); 
    3232 
    3333Configuration::Configuration() 
     
    228228} 
    229229 
     230bool 
     231Configuration::getValueForSetting(std::string path, int32_t &ref) 
     232{ 
     233    libconfig::Setting *s = getSetting( path ); 
     234    if(s) { 
     235        // FIXME: this can be done using the libconfig methods 
     236        Setting::Type t = s->getType(); 
     237        if(t == Setting::TypeInt) { 
     238            ref = *s; 
     239            debugOutput(DEBUG_LEVEL_VERBOSE, "path '%s' has value %d\n", path.c_str(), ref); 
     240            return true; 
     241        } else { 
     242            debugOutput(DEBUG_LEVEL_VERBOSE, "path '%s' has wrong type\n", path.c_str()); 
     243            return false; 
     244        } 
     245    } else { 
     246        debugOutput(DEBUG_LEVEL_VERBOSE, "path '%s' not found\n", path.c_str()); 
     247        return false; 
     248    } 
     249} 
     250 
     251bool 
     252Configuration::getValueForSetting(std::string path, int64_t &ref) 
     253{ 
     254    libconfig::Setting *s = getSetting( path ); 
     255    if(s) { 
     256        // FIXME: this can be done using the libconfig methods 
     257        Setting::Type t = s->getType(); 
     258        if(t == Setting::TypeInt64) { 
     259            ref = *s; 
     260            debugOutput(DEBUG_LEVEL_VERBOSE, "path '%s' has value %d\n", path.c_str(), ref); 
     261            return true; 
     262        } else { 
     263            debugOutput(DEBUG_LEVEL_VERBOSE, "path '%s' has wrong type\n", path.c_str()); 
     264            return false; 
     265        } 
     266    } else { 
     267        debugOutput(DEBUG_LEVEL_VERBOSE, "path '%s' not found\n", path.c_str()); 
     268        return false; 
     269    } 
     270} 
     271 
     272libconfig::Setting * 
     273Configuration::getSetting( std::string path ) 
     274{ 
     275    for ( std::vector<ConfigFile *>::iterator it = m_ConfigFiles.begin(); 
     276      it != m_ConfigFiles.end(); 
     277      ++it ) 
     278    { 
     279        ConfigFile *c = *it; 
     280        try { 
     281            Setting &s = c->lookup(path); 
     282            return &s; 
     283        } catch (...) { 
     284            debugOutput(DEBUG_LEVEL_VERBOSE, "  %s has no setting %s\n", 
     285                        c->getName().c_str(), path.c_str()); 
     286        } 
     287    } 
     288    return NULL; 
     289} 
     290 
    230291 
    231292Configuration::VendorModelEntry 
  • trunk/libffado/src/libutil/Configuration.h

    r1336 r1498  
    113113    static bool isValid( const VendorModelEntry& vme ); 
    114114 
     115    // access functions 
     116    /** 
     117     * @brief retrieves a setting for a given path 
     118     *  
     119     * the value in the ref parameter is not changed if 
     120     * the function returns false. 
     121     *  
     122     * @param path path to the setting 
     123     * @param ref reference to the integer that will hold the value. 
     124     * @return true if successful, false if not 
     125     */ 
     126    bool getValueForSetting(std::string path, int32_t &ref); 
     127    bool getValueForSetting(std::string path, int64_t &ref); 
     128 
    115129    virtual void setVerboseLevel(int l) {setDebugLevel(l);}; 
    116130    virtual void show(); 
    117131 
    118132private: 
     133    libconfig::Setting *getSetting( std::string path ); 
     134 
    119135    int findFileName(std::string s); 
    120136 
  • trunk/libffado/src/libutil/Functors.h

    r960 r1498  
    2626 
    2727#include <semaphore.h> 
     28#include <vector> 
    2829 
    2930namespace Util { 
     
    3637 
    3738    virtual void operator() () = 0; 
     39    virtual bool matchCallee(void *) = 0; 
    3840}; 
     41 
     42typedef std::vector<Functor *> FunctorVector; 
     43typedef std::vector<Functor *>::iterator FunctorVectorIterator; 
    3944 
    4045//////////////////////////////////////////////////////////////////////// 
     
    7479            } 
    7580            if (m_bDelete) { 
    76             delete this; 
     81                delete this; 
     82            } 
    7783        } 
    78     } 
     84    virtual bool matchCallee(void *p) 
     85        { 
     86            return p == (void *)m_pCallee; 
     87        } 
    7988 
    8089private: 
     
    126135    } 
    127136 
     137    virtual bool matchCallee(void *p) 
     138        { 
     139            return p == (void *)m_pCallee; 
     140        } 
     141 
    128142private: 
    129143    CalleePtr  m_pCallee; 
     
    167181            } 
    168182        } 
     183    virtual bool matchCallee(void *p) 
     184        { 
     185            return false; 
     186        } 
    169187 
    170188private: 
  • trunk/libffado/src/libutil/PosixThread.cpp

    r1336 r1498  
    125125 
    126126        memset(&rt_param, 0, sizeof(rt_param)); 
    127         rt_param.sched_priority = fPriority; 
     127        if(fPriority <= 0) { 
     128            debugWarning("Clipping to minimum priority (%d -> 1)\n", fPriority); 
     129            rt_param.sched_priority = 1; 
     130        } else if(fPriority >= 99) { 
     131            debugWarning("Clipping to maximum priority (%d -> 98)\n", fPriority); 
     132            rt_param.sched_priority = 98; 
     133        } else { 
     134            rt_param.sched_priority = fPriority; 
     135        } 
    128136 
    129137        if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) { 
     
    133141 
    134142        if ((res = pthread_create(&fThread, &attributes, ThreadHandler, this))) { 
    135             debugError("Cannot set create thread %d %s\n", res, strerror(res)); 
     143            debugError("Cannot create realtime thread (%d: %s)\n", res, strerror(res)); 
     144            debugError(" priority: %d %s\n", fPriority); 
    136145            return -1; 
    137146        } 
     
    142151 
    143152        if ((res = pthread_create(&fThread, 0, ThreadHandler, this))) { 
    144             debugError("Cannot set create thread %d %s\n", res, strerror(res)); 
     153            debugError("Cannot create thread %d %s\n", res, strerror(res)); 
    145154            return -1; 
    146155        } 
     
    188197 
    189198    memset(&rtparam, 0, sizeof(rtparam)); 
    190     rtparam.sched_priority = fPriority; 
     199    if(fPriority <= 0) { 
     200        debugWarning("Clipping to minimum priority (%d -> 1)\n", fPriority); 
     201        rtparam.sched_priority = 1; 
     202    } else if(fPriority >= 99) { 
     203        debugWarning("Clipping to maximum priority (%d -> 98)\n", fPriority); 
     204        rtparam.sched_priority = 98; 
     205    } else { 
     206        rtparam.sched_priority = fPriority; 
     207    } 
    191208 
    192209    //if ((res = pthread_setschedparam(fThread, SCHED_FIFO, &rtparam)) != 0) { 
  • trunk/libffado/src/libutil/TimestampedBuffer.cpp

    r1336 r1498  
    959959#ifdef DEBUG 
    960960    // check whether the update is within the allowed bounds 
    961 /*    const float max_deviation = (50.0/100.0); // maximal relative difference considered normal 
    962     ffado_timestamp_t one_update_step = nbframes * getRate(); 
    963     ffado_timestamp_t max_abs_diff = one_update_step * (1.0 + max_deviation);*/ 
    964     ffado_timestamp_t max_abs_diff = 200; 
     961    ffado_timestamp_t max_abs_diff = 3072/2; // half a cycle is what we consider 'normal' 
    965962 
    966963    debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 
  • trunk/libffado/src/motu/motu_avdevice.cpp

    r1361 r1498  
    6363    {FW_VENDORID_MOTU, 0, 0x00000001, 0x000001f2, MOTU_MODEL_828MkI, "MOTU", "828MkI"}, 
    6464    {FW_VENDORID_MOTU, 0, 0x00000005, 0x000001f2, MOTU_MODEL_896HD, "MOTU", "896HD"}, 
     65    {FW_VENDORID_MOTU, 0, 0x00000015, 0x000001f2, MOTU_MODEL_828mk3, "MOTU", "828Mk3"}, 
    6566}; 
    6667 
     
    6869const PortEntry Ports_828MKI[] = 
    6970{ 
    70     {"Analog1", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10}, 
    71     {"Analog2", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13}, 
    72     {"Analog3", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16}, 
    73     {"Analog4", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19}, 
    74     {"Analog5", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 22}, 
    75     {"Analog6", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 25}, 
    76     {"Analog7", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 28}, 
    77     {"Analog8", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 31}, 
    78     {"SPDIF1", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 34}, 
    79     {"SPDIF2", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 37}, 
    80     {"ADAT1", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 40}, 
    81     {"ADAT2", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 43}, 
    82     {"ADAT3", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 46}, 
    83     {"ADAT4", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 49}, 
    84     {"ADAT5", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 52}, 
    85     {"ADAT6", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 55}, 
    86     {"ADAT7", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 58}, 
    87     {"ADAT8", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 61}, 
     71    {"Analog1", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10}, 
     72    {"Analog2", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13}, 
     73    {"Analog3", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16}, 
     74    {"Analog4", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19}, 
     75    {"Analog5", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 22}, 
     76    {"Analog6", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 25}, 
     77    {"Analog7", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 28}, 
     78    {"Analog8", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 31}, 
     79    {"SPDIF1", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 34}, 
     80    {"SPDIF2", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 37}, 
     81    {"ADAT1", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 40}, 
     82    {"ADAT2", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 43}, 
     83    {"ADAT3", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 46}, 
     84    {"ADAT4", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 49}, 
     85    {"ADAT5", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 52}, 
     86    {"ADAT6", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 55}, 
     87    {"ADAT7", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 58}, 
     88    {"ADAT8", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 61}, 
    8889}; 
    8990 
    9091const PortEntry Ports_896HD[] = 
    9192{ 
    92     {"Mix-L", MOTU_DIR_IN, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 10}, 
    93     {"Mix-R", MOTU_DIR_IN, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 13}, 
    94     {"Phones-L", MOTU_DIR_OUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 10}, 
    95     {"Phones-R", MOTU_DIR_OUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 13}, 
    96     {"Analog1", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 16}, 
    97     {"Analog1", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 10}, 
    98     {"Analog2", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 19}, 
    99     {"Analog2", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 13}, 
    100     {"Analog3", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 22}, 
    101     {"Analog3", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 16}, 
    102     {"Analog4", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 25}, 
    103     {"Analog4", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 19}, 
    104     {"Analog5", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 28}, 
    105     {"Analog5", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 22}, 
    106     {"Analog6", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 31}, 
    107     {"Analog6", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 25}, 
    108     {"Analog7", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 34}, 
    109     {"Analog7", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 28}, 
    110     {"Analog8", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 37}, 
    111     {"Analog8", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 31}, 
    112     {"MainOut-L", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 40}, 
    113     {"MainOut-R", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 43}, 
    114     {"AES/EBU1", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 46}, 
    115     {"AES/EBU2", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 49}, 
    116     {"ADAT1", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 52}, 
    117     {"ADAT2", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 55}, 
    118     {"ADAT3", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 58}, 
    119     {"ADAT4", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 61}, 
    120     {"ADAT5", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 64}, 
    121     {"ADAT6", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 67}, 
    122     {"ADAT7", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 70}, 
    123     {"ADAT8", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 73}, 
     93    {"Mix-L", MOTU_PA_IN | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 10}, 
     94    {"Mix-R", MOTU_PA_IN | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 13}, 
     95    {"Phones-L", MOTU_PA_OUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 10}, 
     96    {"Phones-R", MOTU_PA_OUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 13}, 
     97    {"Analog1", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 16}, 
     98    {"Analog1", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 10}, 
     99    {"Analog2", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 19}, 
     100    {"Analog2", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 13}, 
     101    {"Analog3", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 22}, 
     102    {"Analog3", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 16}, 
     103    {"Analog4", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 25}, 
     104    {"Analog4", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 19}, 
     105    {"Analog5", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 28}, 
     106    {"Analog5", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 22}, 
     107    {"Analog6", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 31}, 
     108    {"Analog6", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 25}, 
     109    {"Analog7", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 34}, 
     110    {"Analog7", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 28}, 
     111    {"Analog8", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 37}, 
     112    {"Analog8", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 31}, 
     113    {"MainOut-L", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 40}, 
     114    {"MainOut-R", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 43}, 
     115    {"AES/EBU1", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 46}, 
     116    {"AES/EBU2", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 49}, 
     117    {"ADAT1", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 52}, 
     118    {"ADAT2", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 55}, 
     119    {"ADAT3", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 58}, 
     120    {"ADAT4", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 61}, 
     121    {"ADAT5", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 64}, 
     122    {"ADAT6", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 67}, 
     123    {"ADAT7", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 70}, 
     124    {"ADAT8", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 73}, 
    124125}; 
    125126 
    126127const PortEntry Ports_828MKII[] = 
    127128{ 
    128     {"Main-L", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 40}, 
    129     {"Main-R", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 43}, 
    130     {"Mix-L", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10}, 
    131     {"Mix-R", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13}, 
    132     {"Analog1", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16}, 
    133     {"Analog2", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19}, 
    134     {"Analog3", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 22}, 
    135     {"Analog4", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 25}, 
    136     {"Analog5", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 28}, 
    137     {"Analog6", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 31}, 
    138     {"Analog7", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 34}, 
    139     {"Analog8", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 37}, 
    140     {"Phones-L", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10}, 
    141     {"Phones-R", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13}, 
    142     {"Mic1", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 40}, 
    143     {"Mic2", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 43}, 
    144     {"SPDIF1", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 46}, 
    145     {"SPDIF2", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 49}, 
    146     {"ADAT1", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 52}, 
    147     {"ADAT2", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 55}, 
    148     {"ADAT3", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 58}, 
    149     {"ADAT4", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 61}, 
    150     {"ADAT5", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 64}, 
    151     {"ADAT6", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 67}, 
    152     {"ADAT7", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 70}, 
    153     {"ADAT8", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 73}, 
     129    {"Main-L", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 40}, 
     130    {"Main-R", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 43}, 
     131    {"Mix-L", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10}, 
     132    {"Mix-R", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13}, 
     133    {"Analog1", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16}, 
     134    {"Analog2", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19}, 
     135    {"Analog3", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 22}, 
     136    {"Analog4", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 25}, 
     137    {"Analog5", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 28}, 
     138    {"Analog6", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 31}, 
     139    {"Analog7", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 34}, 
     140    {"Analog8", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 37}, 
     141    {"Phones-L", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10}, 
     142    {"Phones-R", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13}, 
     143    {"Mic1", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 40}, 
     144    {"Mic2", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 43}, 
     145    {"SPDIF1", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 46}, 
     146    {"SPDIF2", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 49}, 
     147    {"ADAT1", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 52}, 
     148    {"ADAT2", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 55}, 
     149    {"ADAT3", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 58}, 
     150    {"ADAT4", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 61}, 
     151    {"ADAT5", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 64}, 
     152    {"ADAT6", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 67}, 
     153    {"ADAT7", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 70}, 
     154    {"ADAT8", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 73}, 
    154155}; 
    155156 
    156157const PortEntry Ports_TRAVELER[] =  
    157158{ 
    158     {"Mix-L", MOTU_DIR_IN, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 10}, 
    159     {"Mix-R", MOTU_DIR_IN, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 13}, 
    160     {"Phones-L", MOTU_DIR_OUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 10}, 
    161     {"Phones-R", MOTU_DIR_OUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 13}, 
    162     {"Analog1", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 16}, 
    163     {"Analog1", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 10}, 
    164     {"Analog2", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 19}, 
    165     {"Analog2", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 13}, 
    166     {"Analog3", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 22}, 
    167     {"Analog3", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 16}, 
    168     {"Analog4", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 25}, 
    169     {"Analog4", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 19}, 
    170     {"Analog5", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 28}, 
    171     {"Analog5", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 22}, 
    172     {"Analog6", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 31}, 
    173     {"Analog6", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 25}, 
    174     {"Analog7", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 34}, 
    175     {"Analog7", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 28}, 
    176     {"Analog8", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 37}, 
    177     {"Analog8", MOTU_DIR_INOUT, MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 31}, 
    178     {"AES/EBU1", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 40}, 
    179     {"AES/EBU2", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 43}, 
    180     {"SPDIF1", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_OFF|MOTU_PA_OPTICAL_ADAT, 46}, 
    181     {"SPDIF2", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_OFF|MOTU_PA_OPTICAL_ADAT, 49}, 
    182     {"Toslink1", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_TOSLINK, 46}, 
    183     {"Toslink2", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_TOSLINK, 49}, 
    184     {"ADAT1", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 52}, 
    185     {"ADAT2", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 55}, 
    186     {"ADAT3", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 58}, 
    187     {"ADAT4", MOTU_DIR_INOUT, MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 61}, 
    188     {"ADAT5", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 64}, 
    189     {"ADAT6", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 67}, 
    190     {"ADAT7", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 70}, 
    191     {"ADAT8", MOTU_DIR_INOUT, MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 73}, 
     159    {"Mix-L", MOTU_PA_IN | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 10}, 
     160    {"Mix-R", MOTU_PA_IN | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 13}, 
     161    {"Phones-L", MOTU_PA_OUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 10}, 
     162    {"Phones-R", MOTU_PA_OUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 13}, 
     163    {"Analog1", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 16}, 
     164    {"Analog1", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 10}, 
     165    {"Analog2", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 19}, 
     166    {"Analog2", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 13}, 
     167    {"Analog3", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 22}, 
     168    {"Analog3", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 16}, 
     169    {"Analog4", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 25}, 
     170    {"Analog4", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 19}, 
     171    {"Analog5", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 28}, 
     172    {"Analog5", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 22}, 
     173    {"Analog6", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 31}, 
     174    {"Analog6", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 25}, 
     175    {"Analog7", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 34}, 
     176    {"Analog7", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 28}, 
     177    {"Analog8", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 37}, 
     178    {"Analog8", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 31}, 
     179    {"AES/EBU1", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 40}, 
     180    {"AES/EBU2", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 43}, 
     181    {"SPDIF1", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_OFF|MOTU_PA_OPTICAL_ADAT, 46}, 
     182    {"SPDIF2", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_OFF|MOTU_PA_OPTICAL_ADAT, 49}, 
     183    {"Toslink1", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_TOSLINK, 46}, 
     184    {"Toslink2", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_TOSLINK, 49}, 
     185    {"ADAT1", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 52}, 
     186    {"ADAT2", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 55}, 
     187    {"ADAT3", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 58}, 
     188    {"ADAT4", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 61}, 
     189    {"ADAT5", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 64}, 
     190    {"ADAT6", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 67}, 
     191    {"ADAT7", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 70}, 
     192    {"ADAT8", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 73}, 
    192193}; 
    193194 
    194195const PortEntry Ports_ULTRALITE[] = 
    195196{ 
    196     {"Main-L", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 46}, 
    197     {"Main-R", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 49}, 
    198     {"Padding1", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY|MOTU_PA_PADDING, 46}, 
    199     {"Padding2", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY|MOTU_PA_PADDING, 49}, 
    200     {"Mix-L", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10}, 
    201     {"Mix-R", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13}, 
    202     {"Mic1", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16}, 
    203     {"Mic2", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19}, 
    204     {"Analog1", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16}, 
    205     {"Analog2", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19}, 
    206     {"Analog3", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 22}, 
    207     {"Analog4", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 25}, 
    208     {"Analog5", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 28}, 
    209     {"Analog6", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 31}, 
    210     {"Analog7", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 34}, 
    211     {"Analog8", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 37}, 
    212     {"Phones-L", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10}, 
    213     {"Phones-R", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13}, 
    214     {"SPDIF1", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 40}, 
    215     {"SPDIF2", MOTU_DIR_INOUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 43}, 
     197    {"Main-L", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 40}, 
     198    {"Main-R", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 43}, 
     199    {"Mix-L", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10}, 
     200    {"Mix-R", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13}, 
     201    {"Mic1", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16}, 
     202    {"Mic2", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19}, 
     203    {"Analog1", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16}, 
     204    {"Analog2", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19}, 
     205    {"Analog3", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 22}, 
     206    {"Analog4", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 25}, 
     207    {"Analog5", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 28}, 
     208    {"Analog6", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 31}, 
     209    {"Analog7", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 34}, 
     210    {"Analog8", MOTU_PA_INOUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 37}, 
     211    {"Phones-L", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10}, 
     212    {"Phones-R", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13}, 
     213    {"Padding1", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY|MOTU_PA_PADDING, 46}, 
     214    {"Padding2", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY|MOTU_PA_PADDING, 49}, 
     215    {"SPDIF1", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 46}, 
     216    {"SPDIF2", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 49}, 
    216217}; 
    217218 
    218219const PortEntry Ports_8PRE[] = 
    219220{ 
    220     {"Analog1", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16}, 
    221     {"Analog2", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19}, 
    222     {"Analog3", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 22}, 
    223     {"Analog4", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 25}, 
    224     {"Analog5", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 28}, 
    225     {"Analog6", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 31}, 
    226     {"Analog7", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 34}, 
    227     {"Analog8", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 37}, 
    228     {"Mix-L", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10}, 
    229     {"Mix-R", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13}, 
    230     {"Main-L", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16}, 
    231     {"Main-R", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19}, 
    232     {"Phones-L", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10}, 
    233     {"Phones-R", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13}, 
    234     {"ADAT1", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 40}, 
    235     {"ADAT1", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 22}, 
    236     {"ADAT2", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 43}, 
    237     {"ADAT2", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 25}, 
    238     {"ADAT3", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 46}, 
    239     {"ADAT3", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 28}, 
    240     {"ADAT4", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 49}, 
    241     {"ADAT4", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 31}, 
    242     {"ADAT5", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 52}, 
    243     {"ADAT5", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 34}, 
    244     {"ADAT6", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 55}, 
    245     {"ADAT6", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 37}, 
    246     {"ADAT7", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 58}, 
    247     {"ADAT7", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 40}, 
    248     {"ADAT8", MOTU_DIR_IN, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 61}, 
    249     {"ADAT8", MOTU_DIR_OUT, MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 43}, 
     221    {"Analog1", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16}, 
     222    {"Analog2", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19}, 
     223    {"Analog3", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 22}, 
     224    {"Analog4", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 25}, 
     225    {"Analog5", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 28}, 
     226    {"Analog6", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 31}, 
     227    {"Analog7", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 34}, 
     228    {"Analog8", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 37}, 
     229    {"Mix-L", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10}, 
     230    {"Mix-R", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13}, 
     231    {"Main-L", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 16}, 
     232    {"Main-R", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 19}, 
     233    {"Phones-L", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 10}, 
     234    {"Phones-R", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ANY, 13}, 
     235    {"ADAT1", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 40}, 
     236    {"ADAT1", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 22}, 
     237    {"ADAT2", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 43}, 
     238    {"ADAT2", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 25}, 
     239    {"ADAT3", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 46}, 
     240    {"ADAT3", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 28}, 
     241    {"ADAT4", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 49}, 
     242    {"ADAT4", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 31}, 
     243    {"ADAT5", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 52}, 
     244    {"ADAT5", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 34}, 
     245    {"ADAT6", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 55}, 
     246    {"ADAT6", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 37}, 
     247    {"ADAT7", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 58}, 
     248    {"ADAT7", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 40}, 
     249    {"ADAT8", MOTU_PA_IN | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 61}, 
     250    {"ADAT8", MOTU_PA_OUT | MOTU_PA_RATE_ANY|MOTU_PA_OPTICAL_ADAT, 43}, 
     251}; 
     252 
     253const PortEntry Ports_828mk3[] =  
     254
     255    {"Mix-L", MOTU_PA_IN | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 10}, 
     256    {"Mix-R", MOTU_PA_IN | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 13}, 
     257    {"Phones-L", MOTU_PA_OUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 10}, 
     258    {"Phones-R", MOTU_PA_OUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 13}, 
     259    {"Analog1", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 16}, 
     260    {"Analog1", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 10}, 
     261    {"Analog2", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 19}, 
     262    {"Analog2", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 13}, 
     263    {"Analog3", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 22}, 
     264    {"Analog3", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 16}, 
     265    {"Analog4", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 25}, 
     266    {"Analog4", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 19}, 
     267    {"Analog5", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 28}, 
     268    {"Analog5", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 22}, 
     269    {"Analog6", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 31}, 
     270    {"Analog6", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 25}, 
     271    {"Analog7", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 34}, 
     272    {"Analog7", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 28}, 
     273    {"Analog8", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ANY, 37}, 
     274    {"Analog8", MOTU_PA_INOUT | MOTU_PA_RATE_4x|MOTU_PA_OPTICAL_ANY, 31}, 
     275    {"SPDIF1", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_OFF|MOTU_PA_OPTICAL_ADAT, 40}, 
     276    {"SPDIF2", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_OFF|MOTU_PA_OPTICAL_ADAT, 43}, 
     277    {"Padding1", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_OFF|MOTU_PA_OPTICAL_ADAT|MOTU_PA_PADDING, 46}, 
     278    {"Padding2", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_OFF|MOTU_PA_OPTICAL_ADAT|MOTU_PA_PADDING, 49}, 
     279    {"Toslink1", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_TOSLINK, 40}, 
     280    {"Toslink2", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_TOSLINK, 43}, 
     281    {"Toslink3", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_TOSLINK, 46}, 
     282    {"Toslink4", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_TOSLINK, 49}, 
     283    {"ADAT1", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 52}, 
     284    {"ADAT2", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 55}, 
     285    {"ADAT3", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 58}, 
     286    {"ADAT4", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 61}, 
     287    {"ADAT5", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 64}, 
     288    {"ADAT6", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 67}, 
     289    {"ADAT7", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 70}, 
     290    {"ADAT8", MOTU_PA_INOUT | MOTU_PA_RATE_1x2x|MOTU_PA_OPTICAL_ADAT, 73}, 
     291    {"ADAT9", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 76}, 
     292    {"ADAT10", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 79}, 
     293    {"ADAT11", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 82}, 
     294    {"ADAT12", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 85}, 
     295    {"ADAT13", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 88}, 
     296    {"ADAT14", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 91}, 
     297    {"ADAT15", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 94}, 
     298    {"ADAT16", MOTU_PA_INOUT | MOTU_PA_RATE_1x|MOTU_PA_OPTICAL_ADAT, 97}, 
    250299}; 
    251300 
     
    301350 
    302351    /* For optical mode controls, the "register" is used to indicate direction */ 
    303     {"Control/OpticalIn_mode", "Optical input mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_IN}, 
    304     {"Control/OpticalOut_mode", "Optical output mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_OUT}, 
     352    {"Control/OpticalIn_mode", "Optical input mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_CTRL_DIR_IN}, 
     353    {"Control/OpticalOut_mode", "Optical output mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_CTRL_DIR_OUT}, 
    305354}; 
    306355 
     
    321370    {"Analog 7", MOTU_CTRL_STD_CHANNEL, 0x0018, }, 
    322371    {"Analog 8", MOTU_CTRL_STD_CHANNEL, 0x001c, }, 
     372    {"AES/EBU 1", MOTU_CTRL_STD_CHANNEL, MOTU_CTRL_NONE, }, 
     373    {"AES/EBU 2", MOTU_CTRL_STD_CHANNEL, MOTU_CTRL_NONE, }, 
    323374    {"SPDIF 1", MOTU_CTRL_STD_CHANNEL, 0x0020, }, 
    324375    {"SPDIF 2", MOTU_CTRL_STD_CHANNEL, 0x0024, }, 
     376    {"ADAT 1", MOTU_CTRL_STD_CHANNEL, MOTU_CTRL_NONE, }, 
     377    {"ADAT 2", MOTU_CTRL_STD_CHANNEL, MOTU_CTRL_NONE, }, 
     378    {"ADAT 3", MOTU_CTRL_STD_CHANNEL, MOTU_CTRL_NONE, }, 
     379    {"ADAT 4", MOTU_CTRL_STD_CHANNEL, MOTU_CTRL_NONE, }, 
     380    {"ADAT 5", MOTU_CTRL_STD_CHANNEL, MOTU_CTRL_NONE, }, 
     381    {"ADAT 6", MOTU_CTRL_STD_CHANNEL, MOTU_CTRL_NONE, }, 
     382    {"ADAT 7", MOTU_CTRL_STD_CHANNEL, MOTU_CTRL_NONE, }, 
     383    {"ADAT 8", MOTU_CTRL_STD_CHANNEL, MOTU_CTRL_NONE, }, 
    325384}; 
    326385 
     
    345404 
    346405    /* For optical mode controls, the "register" is used to indicate direction */ 
    347     {"Control/OpticalIn_mode", "Optical input mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_IN}, 
    348     {"Control/OpticalOut_mode", "Optical output mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_OUT}, 
     406    {"Control/OpticalIn_mode", "Optical input mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_CTRL_DIR_IN}, 
     407    {"Control/OpticalOut_mode", "Optical output mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_CTRL_DIR_OUT}, 
    349408}; 
    350409 
     
    359418 
    360419    /* For optical mode controls, the "register" is used to indicate direction */ 
    361     {"Control/OpticalIn_mode", "Optical input mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_IN}, 
    362     {"Control/OpticalOut_mode", "Optical output mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_OUT}, 
     420    {"Control/OpticalIn_mode", "Optical input mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_CTRL_DIR_IN}, 
     421    {"Control/OpticalOut_mode", "Optical output mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_CTRL_DIR_OUT}, 
    363422 
    364423    /* For meter controls the "register" indicates which meter controls are available */ 
     
    388447 
    389448    /* For optical mode controls, the "register" is used to indicate direction */ 
    390     {"Control/OpticalIn_mode", "Optical input mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_IN}, 
    391     {"Control/OpticalOut_mode", "Optical output mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_OUT}, 
     449    {"Control/OpticalIn_mode", "Optical input mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_CTRL_DIR_IN}, 
     450    {"Control/OpticalOut_mode", "Optical output mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_CTRL_DIR_OUT}, 
    392451}; 
    393452 
     
    415474    { Ports_828MKI,    N_ELEMENTS( Ports_828MKI ),     48000 }, 
    416475    { Ports_896HD,     N_ELEMENTS( Ports_896HD ),     192000, &Mixer_896HD, }, 
     476    { Ports_828mk3,    N_ELEMENTS( Ports_828mk3 ),    192000 }, 
    417477}; 
    418478 
     
    451511bool 
    452512MotuDevice::buildMixer() { 
    453     unsigned int i; 
    454513    bool result = true; 
    455514    MotuMatrixMixer *fader_mmixer = NULL; 
     
    457516    MotuMatrixMixer *solo_mmixer = NULL; 
    458517    MotuMatrixMixer *mute_mmixer = NULL; 
    459     unsigned int bus, ch; 
    460     debugOutput(DEBUG_LEVEL_VERBOSE, "Building a MOTU mixer...\n"); 
     518    const struct MatrixMixBus *buses = NULL; 
     519    const struct MatrixMixChannel *channels = NULL; 
     520    unsigned int bus, ch, i; 
    461521 
    462522    destroyMixer(); 
    463          
     523 
    464524    // create the mixer object container 
    465525    m_MixerContainer = new Control::Container(this, "Mixer"); 
     
    467527        debugError("Could not create mixer container...\n"); 
    468528        return false; 
     529    } else { 
     530        buses = DevicesProperty[m_motu_model-1].mixer->mixer_buses; 
     531        if (buses == NULL) { 
     532            debugOutput(DEBUG_LEVEL_WARNING, "No buses defined for model %d\n", m_motu_model); 
     533            result = false; 
     534        } 
     535        channels = DevicesProperty[m_motu_model-1].mixer->mixer_channels; 
     536        if (channels == NULL) { 
     537            debugOutput(DEBUG_LEVEL_WARNING, "No channels defined for model %d\n", m_motu_model); 
     538            result = false; 
     539        } 
     540    } 
     541 
     542    if (result == false) { 
     543        return true; 
    469544    } 
    470545 
     
    480555        MOTU_CTRL_MASK_MUTE_VALUE, MOTU_CTRL_MASK_MUTE_SETENABLE); 
    481556    result &= m_MixerContainer->addElement(mute_mmixer); 
    482     const struct MatrixMixBus *buses = DevicesProperty[m_motu_model-1].mixer->mixer_buses; 
     557    buses = DevicesProperty[m_motu_model-1].mixer->mixer_buses; 
    483558    for (bus=0; bus<DevicesProperty[m_motu_model-1].mixer->n_mixer_buses; bus++) { 
    484559        fader_mmixer->addRowInfo(buses[bus].name, 0, buses[bus].address); 
     
    487562        mute_mmixer->addRowInfo(buses[bus].name, 0, buses[bus].address); 
    488563    } 
    489     const struct MatrixMixChannel *channels = DevicesProperty[m_motu_model-1].mixer->mixer_channels; 
     564    channels = DevicesProperty[m_motu_model-1].mixer->mixer_channels; 
    490565    for (ch=0; ch<DevicesProperty[m_motu_model-1].mixer->n_mixer_channels; ch++) { 
    491566        uint32_t flags = channels[ch].flags; 
     
    807882} 
    808883 
     884enum FFADODevice::eStreamingState 
     885MotuDevice::getStreamingState() 
     886{ 
     887    unsigned int val = ReadRegister(MOTU_REG_ISOCTRL); 
     888    /* Streaming is active if either bit 22 (Motu->PC streaming 
     889     * enable) or bit 30 (PC->Motu streaming enable) is set. 
     890     */ 
     891    debugOutput(DEBUG_LEVEL_VERBOSE, "MOTU_REG_ISOCTRL: %08x\n", val); 
     892 
     893    if((val & 0x40400000) != 0) { 
     894        return eSS_Both; 
     895    } else if ((val & 0x40000000) != 0) { 
     896        return eSS_Receiving; 
     897    } else if ((val & 0x00400000) != 0) { 
     898        return eSS_Sending; 
     899    } else { 
     900        return eSS_Idle; 
     901    } 
     902} 
     903 
    809904int 
    810905MotuDevice::getSamplingFrequency( ) { 
     
    903998        // port if the sample rate is set to a 1x or 2x rate later. 
    904999        if (cancel_adat) { 
    905             setOpticalMode(MOTU_DIR_INOUT, MOTU_OPTICAL_MODE_OFF); 
     1000            setOpticalMode(MOTU_CTRL_DIR_INOUT, MOTU_OPTICAL_MODE_OFF); 
    9061001        } 
    9071002 
     
    9181013        } 
    9191014 
    920         // In other OSes bit 26 of MOTU_REG_CLK_CTRL always seems 
    921         // to be set when this register is written to although the 
    922         // reason isn't currently known.  When we set it, it appears 
    923         // to prevent output being produced so we'll leave it unset 
    924         // until we work out what's going on.  Other systems write 
    925         // to MOTU_REG_CLK_CTRL multiple times, so that may be 
    926         // part of the mystery. 
    927         //   value |= 0x04000000; 
     1015        // Bits 24-26 of MOTU_REG_CLK_CTRL behave a little differently 
     1016        // depending on the model.  In addition, different bit patterns are 
     1017        // written depending on whether streaming is enabled, disabled or is 
     1018        // changing state.  For now we go with the combination used when 
     1019        // streaming is enabled since it seems to work for the other states 
     1020        // as well.  Since device muting can be effected by these bits, we 
     1021        // may utilise this in future during streaming startup to prevent 
     1022        // noises during stabilisation. 
     1023        // 
     1024        // For most models (possibly all except the Ultralite) all 3 bits 
     1025        // can be zero and audio is still output. 
     1026        // 
     1027        // For the Traveler, if bit 26 is set (as it is under other OSes), 
     1028        // bit 25 functions as a device mute bit: if set, audio is output 
     1029        // while if 0 the entire device is muted.  If bit 26 is unset, 
     1030        // setting bit 25 doesn't appear to be detrimental. 
     1031        // 
     1032        // For the Ultralite, other OSes leave bit 26 unset.  However, unlike 
     1033        // other devices bit 25 seems to function as a mute bit in this case. 
     1034        // 
     1035        // The function of bit 24 is currently unknown.  Other OSes set it 
     1036        // for all devices so we will too. 
     1037        reg &= 0xf8ffffff; 
     1038        if (m_motu_model == MOTU_MODEL_TRAVELER) 
     1039            reg |= 0x04000000; 
     1040        reg |= 0x03000000; 
    9281041        if (WriteRegister(MOTU_REG_CLK_CTRL, reg) == 0) { 
    9291042            supported=true; 
     
    12651378    asprintf(&buff,"%s_pbk_MIDI0",id.c_str()); 
    12661379    p = new Streaming::MotuMidiPort(*m_transmitProcessor, buff, 
    1267         Streaming::Port::E_Capture, 4); 
     1380        Streaming::Port::E_Playback, 4); 
    12681381    if (!p) { 
    12691382        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n", buff); 
     
    14771590 
    14781591unsigned int i; 
    1479 unsigned int dir = direction==Streaming::Port::E_Capture?MOTU_DIR_IN:MOTU_DIR_OUT; 
     1592unsigned int dir = direction==Streaming::Port::E_Capture?MOTU_PA_IN:MOTU_PA_OUT; 
    14801593unsigned int flags = (1 << ( optical_mode + 4 )); 
    14811594 
     
    14901603    // pseudo-ports when calculating the event size. 
    14911604    for (i=0; i < DevicesProperty[m_motu_model-1].n_port_entries; i++) { 
    1492         if (( DevicesProperty[m_motu_model-1].port_entry[i].port_dir & dir ) && 
     1605        if (( DevicesProperty[m_motu_model-1].port_entry[i].port_flags & dir ) && 
    14931606           ( DevicesProperty[m_motu_model-1].port_entry[i].port_flags & MOTU_PA_RATE_MASK & flags ) && 
    14941607           ( DevicesProperty[m_motu_model-1].port_entry[i].port_flags & MOTU_PA_OPTICAL_MASK & flags )) { 
     
    15381651unsigned int i; 
    15391652char *buff; 
    1540 unsigned int dir = direction==Streaming::Port::E_Capture?MOTU_DIR_IN:MOTU_DIR_OUT; 
     1653unsigned int dir = direction==Streaming::Port::E_Capture?MOTU_PA_IN:MOTU_PA_OUT; 
    15411654unsigned int flags = (1 << ( optical_mode + 4 )); 
    15421655 
     
    15611674 
    15621675    for (i=0; i < DevicesProperty[m_motu_model-1].n_port_entries; i++) { 
    1563         if (( DevicesProperty[m_motu_model-1].port_entry[i].port_dir & dir ) && 
     1676        if (( DevicesProperty[m_motu_model-1].port_entry[i].port_flags & dir ) && 
    15641677           ( DevicesProperty[m_motu_model-1].port_entry[i].port_flags & MOTU_PA_RATE_MASK & flags ) && 
    15651678           ( DevicesProperty[m_motu_model-1].port_entry[i].port_flags & MOTU_PA_OPTICAL_MASK & flags ) && 
  • trunk/libffado/src/motu/motu_avdevice.h

    r1361 r1498  
    3838#define MOTU_BASE_ADDR               0xfffff0000000ULL 
    3939 
     40/* Bitmasks and values used when setting MOTU device registers */ 
    4041#define MOTU_RATE_BASE_44100         (0<<3) 
    4142#define MOTU_RATE_BASE_48000         (1<<3) 
     
    6364#define MOTU_CLKSRC_NONE             0xffff 
    6465#define MOTU_CLKSRC_UNCHANGED        MOTU_CLKSRC_NONE 
    65  
    66 #define MOTU_DIR_IN          1 
    67 #define MOTU_DIR_OUT         2 
    68 #define MOTU_DIR_INOUT       (MOTU_DIR_IN | MOTU_DIR_OUT) 
    6966 
    7067#define MOTU_METER_PEAKHOLD_MASK     0x3800 
     
    103100#define MOTU_PA_OPTICAL_MASK     MOTU_PA_OPTICAL_ANY 
    104101#define MOTU_PA_PADDING          0x0100 
     102#define MOTU_PA_IN               0x0200 
     103#define MOTU_PA_OUT              0x0400 
     104#define MOTU_PA_INOUT            (MOTU_PA_IN | MOTU_PA_OUT) 
     105 
     106/* Generic "direction" flags */ 
     107#define MOTU_DIR_IN          1 
     108#define MOTU_DIR_OUT         2 
     109#define MOTU_DIR_INOUT       (MOTU_DIR_IN | MOTU_DIR_OUT) 
    105110 
    106111class ConfigRom; 
     
    121126    MOTU_MODEL_828MkI   = 0x0005, 
    122127    MOTU_MODEL_896HD    = 0x0006, 
     128    MOTU_MODEL_828mk3   = 0x0007, 
    123129}; 
    124130 
     
    135141struct PortEntry { 
    136142    const char *port_name; 
    137     unsigned int port_dir; 
    138143    unsigned int port_flags; 
    139144    unsigned int port_offset; 
     
    209214    virtual int getStreamCount(); 
    210215    virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i); 
     216    enum FFADODevice::eStreamingState getStreamingState(); 
    211217 
    212218    virtual bool prepare(); 
  • trunk/libffado/src/motu/motu_controls.cpp

    r1336 r1498  
    7676      getName().c_str(), m_register, v); 
    7777 
     78    if (m_register == MOTU_CTRL_NONE) { 
     79        debugOutput(DEBUG_LEVEL_WARNING, "use of MOTU_CTRL_NONE in non-matrix control\n"); 
     80        return true; 
     81    } 
     82 
    7883    // Set the value 
    7984    if (m_setenable_mask) { 
     
    103108      getName().c_str(), m_register); 
    104109 
     110    if (m_register == MOTU_CTRL_NONE) { 
     111        debugOutput(DEBUG_LEVEL_WARNING, "use of MOTU_CTRL_NONE in non-matrix control\n"); 
     112        return 0; 
     113    } 
     114 
    105115    // FIXME: we could just read the appropriate mixer status field from the 
    106116    // receive stream processor once we work out an efficient way to do this. 
     
    125135    unsigned int val; 
    126136    debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for channel fader 0x%04x to %d\n", m_register, v); 
     137 
     138    if (m_register == MOTU_CTRL_NONE) { 
     139        debugOutput(DEBUG_LEVEL_WARNING, "use of MOTU_CTRL_NONE in non-matrix control\n"); 
     140        return true; 
     141    } 
    127142 
    128143    val = v<0?0:v; 
     
    142157    debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for channel fader 0x%04x\n", m_register); 
    143158 
     159    // Silently swallow attempts to read non-existent controls for now 
     160    if (m_register == MOTU_CTRL_NONE) { 
     161        debugOutput(DEBUG_LEVEL_WARNING, "use of MOTU_CTRL_NONE in non-matrix control\n"); 
     162        return 0; 
     163    } 
     164 
    144165    // FIXME: we could just read the appropriate mixer status field from the 
    145166    // receive stream processor once we work out an efficient way to do this. 
     
    164185    unsigned int val; 
    165186    debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for channel pan 0x%04x to %d\n", m_register, v); 
     187 
     188    if (m_register == MOTU_CTRL_NONE) { 
     189        debugOutput(DEBUG_LEVEL_WARNING, "use of MOTU_CTRL_NONE in non-matrix control\n"); 
     190        return true; 
     191    } 
    166192 
    167193    val = ((v<-64?-64:v)+64) & 0xff; 
     
    181207    debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for channel pan 0x%04x\n", m_register); 
    182208 
     209    // Silently swallow attempts to read non-existent controls for now 
     210    if (m_register == MOTU_CTRL_NONE) { 
     211        debugOutput(DEBUG_LEVEL_WARNING, "use of MOTU_CTRL_NONE in non-matrix control\n"); 
     212        return 0; 
     213    } 
     214 
    183215    // FIXME: we could just read the appropriate mixer status field from the 
    184216    // receive stream processor once we work out an efficient way to do this. 
     
    222254uint32_t MotuMatrixMixer::getCellRegister(const unsigned int row, const unsigned int col) 
    223255{ 
     256    if (m_RowInfo.at(row).address==MOTU_CTRL_NONE || 
     257        m_ColInfo.at(col).address==MOTU_CTRL_NONE) 
     258        return MOTU_CTRL_NONE; 
    224259    return m_RowInfo.at(row).address + m_ColInfo.at(col).address; 
    225260} 
     
    262297double ChannelFaderMatrixMixer::setValue(const int row, const int col, const double val) 
    263298{ 
    264     uint32_t v
     299    uint32_t v, reg
    265300    v = val<0?0:(uint32_t)val; 
    266301    if (v > 0x80) 
     
    268303    debugOutput(DEBUG_LEVEL_VERBOSE, "ChannelFader setValue for row %d col %d to %lf (%ld)\n", 
    269304      row, col, val, v); 
    270  
     305    reg = getCellRegister(row,col); 
     306 
     307    // Silently swallow attempts to set non-existent controls for now 
     308    if (reg == MOTU_CTRL_NONE) { 
     309        debugOutput(DEBUG_LEVEL_VERBOSE, "ignoring control marked as non-existent\n"); 
     310        return true; 
     311    } 
    271312    // Bit 30 indicates that the channel fader is being set 
    272313    v |= 0x40000000; 
    273     m_parent.WriteRegister(getCellRegister(row,col), v); 
     314    m_parent.WriteRegister(reg, v); 
    274315 
    275316    return true; 
     
    278319double ChannelFaderMatrixMixer::getValue(const int row, const int col) 
    279320{ 
    280     uint32_t val; 
     321    uint32_t val, reg; 
     322    reg = getCellRegister(row,col); 
     323 
     324    // Silently swallow attempts to read non-existent controls for now 
     325    if (reg == MOTU_CTRL_NONE) { 
     326        debugOutput(DEBUG_LEVEL_VERBOSE, "ignoring control marked as non-existent\n"); 
     327        return 0; 
     328    } 
    281329    // FIXME: we could just read the appropriate mixer status field from the 
    282330    // receive stream processor once we work out an efficient way to do this. 
    283     val = m_parent.ReadRegister(getCellRegister(row,col)) & 0xff; 
     331    val = m_parent.ReadRegister(reg) & 0xff; 
    284332 
    285333    debugOutput(DEBUG_LEVEL_VERBOSE, "ChannelFader getValue for row %d col %d = %lu\n", 
     
    300348double ChannelPanMatrixMixer::setValue(const int row, const int col, const double val) 
    301349{ 
    302     uint32_t v
     350    uint32_t v, reg
    303351    v = ((val<-64?-64:(int32_t)val)+64) & 0xff; 
    304352    if (v > 0x80) 
     
    307355    debugOutput(DEBUG_LEVEL_VERBOSE, "ChannelPan setValue for row %d col %d to %lf (%ld)\n", 
    308356      row, col, val, v); 
     357    reg = getCellRegister(row,col); 
     358 
     359    // Silently swallow attempts to set non-existent controls for now 
     360    if (reg == MOTU_CTRL_NONE) { 
     361        debugOutput(DEBUG_LEVEL_VERBOSE, "ignoring control marked as non-existent\n"); 
     362        return true; 
     363    } 
    309364 
    310365    // Bit 31 indicates that pan is being set 
    311366    v = (v << 8) | 0x80000000; 
    312     m_parent.WriteRegister(getCellRegister(row,col), v); 
     367    m_parent.WriteRegister(reg, v); 
    313368 
    314369    return true; 
     
    318373{ 
    319374    int32_t val; 
     375    uint32_t reg; 
     376    reg = getCellRegister(row,col); 
     377 
     378    // Silently swallow attempts to read non-existent controls for now 
     379    if (reg == MOTU_CTRL_NONE) { 
     380        debugOutput(DEBUG_LEVEL_VERBOSE, "ignoring control marked as non-existent\n"); 
     381        return 0; 
     382    } 
     383 
    320384    // FIXME: we could just read the appropriate mixer status field from the 
    321385    // receive stream processor once we work out an efficient way to do this. 
    322     val = m_parent.ReadRegister(getCellRegister(row,col)); 
     386    val = m_parent.ReadRegister(reg); 
    323387    val = ((val >> 8) & 0xff) - 0x40; 
    324388 
     
    348412double ChannelBinSwMatrixMixer::setValue(const int row, const int col, const double val) 
    349413{ 
    350     uint32_t v
     414    uint32_t v, reg
    351415 
    352416    debugOutput(DEBUG_LEVEL_VERBOSE, "BinSw setValue for row %d col %d to %lf (%ld)\n", 
    353417      row, col, val, val==0?0:1); 
     418    reg = getCellRegister(row,col); 
     419 
     420    // Silently swallow attempts to set non-existent controls for now 
     421    if (reg == MOTU_CTRL_NONE) { 
     422        debugOutput(DEBUG_LEVEL_VERBOSE, "ignoring control marked as non-existent\n"); 
     423        return true; 
     424    } 
    354425 
    355426    // Set the value 
     
    362433      // processor (if running) later on.  For now we'll just fetch the 
    363434      // current register value directly when needed. 
    364       v = m_parent.ReadRegister(getCellRegister(row,col)); 
     435      v = m_parent.ReadRegister(reg); 
    365436      if (v==0) 
    366437        v &= ~m_value_mask; 
     
    368439        v |= m_value_mask; 
    369440    } 
    370     m_parent.WriteRegister(getCellRegister(row,col), v); 
     441    m_parent.WriteRegister(reg, v); 
    371442 
    372443    return true; 
     
    375446double ChannelBinSwMatrixMixer::getValue(const int row, const int col) 
    376447{ 
    377     uint32_t val; 
     448    uint32_t val, reg; 
     449    reg = getCellRegister(row,col); 
     450 
     451    // Silently swallow attempts to read non-existent controls for now 
     452    if (reg == MOTU_CTRL_NONE) { 
     453        debugOutput(DEBUG_LEVEL_VERBOSE, "ignoring control marked as non-existent\n"); 
     454        return 0; 
     455    } 
    378456 
    379457    // FIXME: we could just read the appropriate mixer status field from the  
    380458    // receive stream processor once we work out an efficient way to do this. 
    381     val = m_parent.ReadRegister(getCellRegister(row,col)); 
     459    val = m_parent.ReadRegister(reg); 
    382460    val = (val & m_value_mask) != 0; 
    383461 
     
    405483    debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for mix fader 0x%04x to %d\n", m_register, v); 
    406484 
     485    // Silently swallow attempts to set non-existent controls for now 
     486    if (m_register == MOTU_CTRL_NONE) { 
     487        debugOutput(DEBUG_LEVEL_WARNING, "use of MOTU_CTRL_NONE in non-matrix control\n"); 
     488        return true; 
     489    } 
    407490    val = v<0?0:v; 
    408491    if (val > 0x80) 
     
    421504    debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for mix fader 0x%04x\n", m_register); 
    422505 
     506    // Silently swallow attempts to read non-existent controls for now 
     507    if (m_register == MOTU_CTRL_NONE) { 
     508        debugOutput(DEBUG_LEVEL_WARNING, "use of MOTU_CTRL_NONE in non-matrix control\n"); 
     509        return 0; 
     510    } 
     511 
    423512    // FIXME: we could just read the appropriate mixer status field from the 
    424513    // receive stream processor once we work out an efficient way to do this. 
     
    443532    unsigned int val, dest; 
    444533    debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for mix mute 0x%04x to %d\n", m_register, v); 
     534 
     535    // Silently swallow attempts to set non-existent controls for now 
     536    if (m_register == MOTU_CTRL_NONE) { 
     537        debugOutput(DEBUG_LEVEL_WARNING, "use of MOTU_CTRL_NONE in non-matrix control\n"); 
     538        return true; 
     539    } 
    445540 
    446541    // Need to read current destination so we can preserve that when setting 
     
    463558    debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for mix mute 0x%04x\n", m_register); 
    464559 
     560    // Silently swallow attempts to read non-existent controls for now 
     561    if (m_register == MOTU_CTRL_NONE) { 
     562        debugOutput(DEBUG_LEVEL_WARNING, "use of MOTU_CTRL_NONE in non-matrix control\n"); 
     563        return 0; 
     564    } 
     565 
    465566    // FIXME: we could just read the appropriate mixer status field from the 
    466567    // receive stream processor once we work out an efficient way to do this. 
     
    486587    debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for mix destination 0x%04x to %d\n", m_register, v); 
    487588 
     589    // Silently swallow attempts to set non-existent controls for now 
     590    if (m_register == MOTU_CTRL_NONE) { 
     591        debugOutput(DEBUG_LEVEL_WARNING, "use of MOTU_CTRL_NONE in non-matrix control\n"); 
     592        return true; 
     593    } 
    488594    // Need to get current mute status so we can preserve it 
    489595    mute = m_parent.ReadRegister(m_register) & 0x00001000; 
     
    511617    debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for mix destination 0x%04x\n", m_register); 
    512618 
     619    // Silently swallow attempts to read non-existent controls for now 
     620    if (m_register == MOTU_CTRL_NONE) { 
     621        debugOutput(DEBUG_LEVEL_WARNING, "use of MOTU_CTRL_NONE in non-matrix control\n"); 
     622        return true; 
     623    } 
    513624    // FIXME: we could just read the appropriate mixer status field from the 
    514625    // receive stream processor once we work out an efficient way to do this. 
     
    583694    // Set mode as requested.  An invalid setting is effectively ignored. 
    584695    if (v>=0 && v<=3) { 
    585       if (m_register == MOTU_DIR_IN) { 
     696      if (m_register == MOTU_CTRL_DIR_IN) { 
    586697        val = (val & ~0x0300) | ((v & 0x03) << 8); 
    587698      } else { 
     
    605716    // receive stream processor once we work out an efficient way to do this. 
    606717    val = m_parent.ReadRegister(MOTU_REG_ROUTE_PORT_CONF); 
    607     if (m_register == MOTU_DIR_IN) 
     718    if (m_register == MOTU_CTRL_DIR_IN) 
    608719      val = (val >> 8) & 0x03; 
    609720    else 
     
    655766    unsigned int reg, reg_shift; 
    656767    debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for mode %d input pad/trim %d to %d\n", m_mode, m_register, v); 
     768 
     769    if (m_register == MOTU_CTRL_NONE) { 
     770        debugOutput(DEBUG_LEVEL_WARNING, "use of MOTU_CTRL_NONE in non-matrix control\n"); 
     771        return true; 
     772    } 
    657773 
    658774    reg = dev_register(); 
     
    703819    debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for mode %d input pad/trim %d\n", m_mode, m_register); 
    704820 
     821    if (m_register == MOTU_CTRL_NONE) { 
     822        debugOutput(DEBUG_LEVEL_WARNING, "use of MOTU_CTRL_NONE in non-matrix control\n"); 
     823        return 0; 
     824    } 
     825 
    705826    reg = dev_register(); 
    706827    if (reg == 0) 
     
    743864 
    744865void MeterControl::validate(void) { 
    745     if (m_register & (1<< m_shift) == 0) { 
     866    if ((m_register & (1<< m_shift)) == 0) { 
    746867        debugOutput(DEBUG_LEVEL_VERBOSE, "Inconsistent mask/shift: 0x%08x/%d\n", m_register, m_shift); 
    747868    } 
  • trunk/libffado/src/motu/motu_controls.h

    r1361 r1498  
    8181#define MOTU_CTRL_METER_PROG_SRC           0x00000008 
    8282 
     83#define MOTU_CTRL_DIR_IN                   0x00000001 
     84#define MOTU_CTRL_DIR_OUT                  0x00000002 
     85#define MOTU_CTRL_DIR_INOUT                (MOTU_CTRL_DIR_IN | MOTU_CTRL_DIR_OUT) 
     86 
    8387#define MOTU_INFO_MODEL                    0x00000001 
    8488#define MOTU_INFO_IS_STREAMING             0x00000002 
     
    9195#define MOTU_CTRL_TRIMGAINPAD_MAX_CHANNEL  3 
    9296 
     97/* A "register" value used to signify that a particular control in a matrix 
     98 * mixer is not available on the current interface. 
     99 */ 
     100#define MOTU_CTRL_NONE                     0xffffffff 
     101 
    93102class MotuDiscreteCtrl 
    94103    : public Control::Discrete 
  • trunk/libffado/src/SConscript

    r1336 r1498  
    224224        libenv.MergeFlags( "-lrt" ) 
    225225        libenv.MergeFlags( env['LIBRAW1394_FLAGS'] ) 
    226         libenv.MergeFlags( env['LIBAVC1394_FLAGS'] ) 
    227226        libenv.MergeFlags( env['LIBIEC61883_FLAGS'] ) 
    228227        if not env['SERIALIZE_USE_EXPAT']: 
  • trunk/libffado/support/dbus/control-interface.xml

    r1336 r1498  
    1414      <method name="getDescription"> 
    1515          <arg type="s" name="description" direction="out"/> 
     16      </method> 
     17      <method name="canChangeValue"> 
     18          <arg type="b" name="can_change" direction="out"/> 
    1619      </method> 
    1720      <method name="getVerboseLevel"> 
  • trunk/libffado/support/dbus/controlserver.cpp

    r1336 r1498  
    6464} 
    6565 
     66DBus::Bool 
     67Element::canChangeValue() 
     68{ 
     69    return m_Slave.canChangeValue(); 
     70} 
     71 
    6672void 
    6773Element::Lock() 
     
    8187    } else { 
    8288        m_UpdateLock->Unlock(); 
     89    } 
     90} 
     91 
     92bool 
     93Element::isLocked() 
     94{ 
     95    if(m_Parent) { 
     96        return m_Parent->isLocked(); 
     97    } else { 
     98        return m_UpdateLock->isLocked(); 
    8399    } 
    84100} 
     
    341357    debugOutput( DEBUG_LEVEL_VERBOSE, "Creating handler for '%s'\n", 
    342358                 e.getName().c_str() ); 
    343                   
    344     if (dynamic_cast<Control::Container *>(&e) != NULL) { 
    345         debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Container\n"); 
     359    try { 
     360        if (dynamic_cast<Control::Container *>(&e) != NULL) { 
     361            debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Container\n"); 
     362             
     363            return new Container(conn(), std::string(path()+"/"+e.getName()),  
     364                parent, *dynamic_cast<Control::Container *>(&e)); 
     365        } 
    346366         
    347         return new Container(conn(), std::string(path()+"/"+e.getName()),  
    348             parent, *dynamic_cast<Control::Container *>(&e)); 
    349     } 
    350      
    351     if (dynamic_cast<Control::Continuous *>(&e) != NULL) { 
    352         debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Continuous\n"); 
     367        if (dynamic_cast<Control::Continuous *>(&e) != NULL) { 
     368            debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Continuous\n"); 
     369             
     370            return new Continuous(conn(), std::string(path()+"/"+e.getName()), 
     371                parent, *dynamic_cast<Control::Continuous *>(&e)); 
     372        } 
    353373         
    354         return new Continuous(conn(), std::string(path()+"/"+e.getName()), 
    355             parent, *dynamic_cast<Control::Continuous *>(&e)); 
    356     } 
    357      
    358     if (dynamic_cast<Control::Discrete *>(&e) != NULL) { 
    359         debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Discrete\n"); 
     374        if (dynamic_cast<Control::Discrete *>(&e) != NULL) { 
     375            debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Discrete\n"); 
     376             
     377            return new Discrete(conn(), std::string(path()+"/"+e.getName()), 
     378                parent, *dynamic_cast<Control::Discrete *>(&e)); 
     379        } 
    360380         
    361         return new Discrete(conn(), std::string(path()+"/"+e.getName()), 
    362             parent, *dynamic_cast<Control::Discrete *>(&e)); 
    363     } 
    364      
    365     if (dynamic_cast<Control::Text *>(&e) != NULL) { 
    366         debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Text\n"); 
     381        if (dynamic_cast<Control::Text *>(&e) != NULL) { 
     382            debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Text\n"); 
     383             
     384            return new Text(conn(), std::string(path()+"/"+e.getName()), 
     385                parent, *dynamic_cast<Control::Text *>(&e)); 
     386        } 
     387     
     388        if (dynamic_cast<Control::Register *>(&e) != NULL) { 
     389            debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Register\n"); 
     390             
     391            return new Register(conn(), std::string(path()+"/"+e.getName()), 
     392                parent, *dynamic_cast<Control::Register *>(&e)); 
     393        } 
     394     
     395        // note that we have to check this before checking the Enum, 
     396        // since Enum is a base class 
     397        if (dynamic_cast<Control::AttributeEnum *>(&e) != NULL) { 
     398            debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::AttributeEnum\n"); 
     399             
     400            return new AttributeEnum(conn(), std::string(path()+"/"+e.getName()), 
     401                parent, *dynamic_cast<Control::AttributeEnum *>(&e)); 
     402        } 
    367403         
    368         return new Text(conn(), std::string(path()+"/"+e.getName()), 
    369             parent, *dynamic_cast<Control::Text *>(&e)); 
    370     } 
    371  
    372     if (dynamic_cast<Control::Register *>(&e) != NULL) { 
    373         debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Register\n"); 
     404        if (dynamic_cast<Control::Enum *>(&e) != NULL) { 
     405            debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Enum\n"); 
     406             
     407            return new Enum(conn(), std::string(path()+"/"+e.getName()), 
     408                parent, *dynamic_cast<Control::Enum *>(&e)); 
     409        } 
    374410         
    375         return new Register(conn(), std::string(path()+"/"+e.getName()), 
    376             parent, *dynamic_cast<Control::Register *>(&e)); 
    377     } 
    378  
    379     // note that we have to check this before checking the Enum, 
    380     // since Enum is a base class 
    381     if (dynamic_cast<Control::AttributeEnum *>(&e) != NULL) { 
    382         debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::AttributeEnum\n"); 
     411        if (dynamic_cast<ConfigRom *>(&e) != NULL) { 
     412            debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a ConfigRom\n"); 
     413             
     414            return new ConfigRomX(conn(), std::string(path()+"/"+e.getName()), 
     415                parent, *dynamic_cast<ConfigRom *>(&e)); 
     416        } 
    383417         
    384         return new AttributeEnum(conn(), std::string(path()+"/"+e.getName()), 
    385             parent, *dynamic_cast<Control::AttributeEnum *>(&e)); 
    386     } 
    387      
    388     if (dynamic_cast<Control::Enum *>(&e) != NULL) { 
    389         debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Enum\n"); 
     418        if (dynamic_cast<Control::MatrixMixer *>(&e) != NULL) { 
     419            debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::MatrixMixer\n"); 
     420             
     421            return new MatrixMixer(conn(), std::string(path()+"/"+e.getName()), 
     422                parent, *dynamic_cast<Control::MatrixMixer *>(&e)); 
     423        } 
    390424         
    391         return new Enum(conn(), std::string(path()+"/"+e.getName()), 
    392             parent, *dynamic_cast<Control::Enum *>(&e)); 
    393     } 
    394      
    395     if (dynamic_cast<ConfigRom *>(&e) != NULL) { 
    396         debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a ConfigRom\n"); 
    397          
    398         return new ConfigRomX(conn(), std::string(path()+"/"+e.getName()), 
    399             parent, *dynamic_cast<ConfigRom *>(&e)); 
    400     } 
    401      
    402     if (dynamic_cast<Control::MatrixMixer *>(&e) != NULL) { 
    403         debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::MatrixMixer\n"); 
    404          
    405         return new MatrixMixer(conn(), std::string(path()+"/"+e.getName()), 
    406             parent, *dynamic_cast<Control::MatrixMixer *>(&e)); 
    407     } 
    408      
    409     debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Element\n"); 
    410     return new Element(conn(), std::string(path()+"/"+e.getName()), parent, e); 
     425        debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Element\n"); 
     426        return new Element(conn(), std::string(path()+"/"+e.getName()), parent, e); 
     427    } catch (...) { 
     428        debugWarning("Could not register %s\n", std::string(path()+"/"+e.getName()).c_str()); 
     429        if(e.isControlLocked()) { 
     430            e.unlockControl(); 
     431        } 
     432        if(isLocked()) { 
     433            Unlock(); 
     434        } 
     435        return NULL; 
     436    }; 
    411437} 
    412438 
  • trunk/libffado/support/dbus/controlserver.h

    r1336 r1498  
    102102, public DBus::ObjectAdaptor 
    103103{ 
    104 friend class Container; // This should not be necessary since Container derives from Element 
     104friend class Container; // required to have container access other slave elements 
    105105public: 
    106106 
     
    114114    DBus::String getDescription( ); 
    115115 
     116    DBus::Bool canChangeValue( ); 
     117 
    116118    void setVerboseLevel( const DBus::Int32 &); 
    117119    DBus::Int32 getVerboseLevel(); 
     
    120122    void Lock(); 
    121123    void Unlock(); 
     124    bool isLocked(); 
    122125    Util::Mutex* getLock(); 
    123126 
     
    135138class Container 
    136139: public org::ffado::Control::Element::Container 
    137 , public Element 
     140, public DBusControl::Element 
    138141{ 
    139142public: 
  • trunk/libffado/support/dbus/ffado-dbus-server.cpp

    r1336 r1498  
    229229{ 
    230230    struct arguments arguments; 
     231 
     232    printf("-----------------------------------------------\n"); 
     233    printf("FFADO Control DBUS service\n"); 
     234    printf("Part of the FFADO project -- www.ffado.org\n"); 
     235    printf("Version: %s\n", PACKAGE_VERSION); 
     236    printf("(C) 2008, Pieter Palmers\n"); 
     237    printf("This program comes with ABSOLUTELY NO WARRANTY.\n"); 
     238    printf("-----------------------------------------------\n\n"); 
     239 
     240    // check the library version 
     241    const char *libversion = ffado_get_version(); 
     242    const char *progversion = PACKAGE_STRING; 
     243    if(strcmp(libversion, progversion) != 0) { 
     244        printf("Library version mismatch. (required: %s, present: %s)\n", progversion, libversion); 
     245        printf("Please run this application against the exact corresponding library\n"); 
     246        printf("it was compiled for. The most common cause for this is having more\n"); 
     247        printf("than one version of libffado installed.\n\n"); 
     248        return exitfunction(-1); 
     249    } 
    231250 
    232251    // Default values. 
     
    249268    } 
    250269 
    251     debugOutput( DEBUG_LEVEL_NORMAL, "verbose level = %d\n", arguments.verbose); 
    252     debugOutput( DEBUG_LEVEL_NORMAL, "Using ffado library version: %s\n\n", ffado_get_version() ); 
    253  
     270    printMessage(" Discovering devices...\n"); 
    254271    m_deviceManager = new DeviceManager(); 
    255272    if ( !m_deviceManager ) { 
  • trunk/libffado/support/firmware/bridgeco-downloader.cpp

    r1336 r1498  
    2929#include "libieee1394/configrom.h" 
    3030#include "libieee1394/ieee1394service.h" 
     31#include "version.h" 
    3132 
    3233#include <iostream> 
    3334#include <cstdlib> 
    3435#include <cstring> 
     36 
     37#define MAGIC_THAT_SAYS_I_KNOW_WHAT_IM_DOING 0x001807198000LL 
    3538 
    3639using namespace std; 
     
    5255    {"force",     'f', 0,           0,  "Force firmware download" }, 
    5356    {"noboot",    'b', 0,           0,  "Do no start bootloader (bootloader is already running)" }, 
     57    {"magic",     'm', "MAGIC",     0,  "A magic number you have to obtain before this code will work."  
     58                                        "Specifying it means that you accept the risks that come with this tool."}, 
    5459    { 0 } 
    5560}; 
     
    5964main( int argc, char** argv ) 
    6065{ 
     66    printf("-----------------------------------------------\n"); 
     67    printf("BridgeCo BeBoB platform firmware downloader\n"); 
     68    printf("Part of the FFADO project -- www.ffado.org\n"); 
     69    printf("Version: %s\n", PACKAGE_VERSION); 
     70    printf("(C) 2008, Daniel Wagner, Pieter Palmers\n"); 
     71    printf("This program comes with ABSOLUTELY NO WARRANTY.\n"); 
     72    printf("-----------------------------------------------\n\n"); 
    6173 
    6274    // arg parsing 
     
    7688        perror("argument parsing failed:"); 
    7789        return -1; 
     90    } 
     91 
     92    if(args->magic != MAGIC_THAT_SAYS_I_KNOW_WHAT_IM_DOING) { 
     93        printf("Magic number not correct. Please specify the correct magic using the '-m' option.\n"); 
     94        printf("Manipulating firmware can cause your device to magically stop working (a.k.a. 'bricking').\n"); 
     95        printf("Specifying the magic number indicates that you accept the risks involved\n"); 
     96        printf("with using this tool. The magic number can be found in the source code.\n\n"); 
     97        return -1; 
     98    } else { 
     99        printf("YOU HAVE SPECIFIED THE CORRECT MAGIC NUMBER.\n"); 
     100        printf("HENCE YOU ACCEPT THE RISKS INVOLVED.\n"); 
    78101    } 
    79102 
  • trunk/libffado/support/firmware/fireworks-downloader.cpp

    r1336 r1498  
    3838 
    3939#include "devicemanager.h" 
     40#include "version.h" 
    4041 
    4142#include <iostream> 
     
    9697    using namespace std; 
    9798 
     99    printf("-----------------------------------------------\n"); 
     100    printf("ECHO FireWorks platform firmware downloader\n"); 
     101    printf("Part of the FFADO project -- www.ffado.org\n"); 
     102    printf("Version: %s\n", PACKAGE_VERSION); 
     103    printf("(C) 2008, Pieter Palmers\n"); 
     104    printf("This program comes with ABSOLUTELY NO WARRANTY.\n"); 
     105    printf("-----------------------------------------------\n\n"); 
     106 
    98107    memset(args, 0, sizeof(args)); 
    99108 
     
    114123 
    115124    if(args->magic != MAGIC_THAT_SAYS_I_KNOW_WHAT_IM_DOING) { 
    116         printMessage("Magic number not correct. Please specify the correct magic using the '-m' option.\n"); 
    117         printMessage("Manipulating firmware can cause your device to magically stop working (a.k.a. 'bricking').\n"); 
    118         printMessage("Specifying the magic number indicates that you accept the risks involved\n"); 
    119         printMessage("with using this tool. The magic number can be found in the source code.\n"); 
     125        printf("Magic number not correct. Please specify the correct magic using the '-m' option.\n"); 
     126        printf("Manipulating firmware can cause your device to magically stop working (a.k.a. 'bricking').\n"); 
     127        printf("Specifying the magic number indicates that you accept the risks involved\n"); 
     128        printf("with using this tool. The magic number can be found in the source code.\n\n"); 
    120129        return -1; 
    121130    } else { 
    122         printMessage("YOU HAVE SPECIFIED THE CORRECT MAGIC NUMBER.\n"); 
    123         printMessage("HENCE YOU ACCEPT THE RISKS INVOLVED.\n"); 
     131        printf("YOU HAVE SPECIFIED THE CORRECT MAGIC NUMBER.\n"); 
     132        printf("HENCE YOU ACCEPT THE RISKS INVOLVED.\n"); 
    124133    } 
    125134 
  • trunk/libffado/support/firmware/SConscript

    r1185 r1498  
    3131    env.MergeFlags( "-lrt" ) 
    3232    env.MergeFlags( env['LIBRAW1394_FLAGS'] ) 
    33     env.MergeFlags( env['LIBAVC1394_FLAGS'] ) 
    3433    env.MergeFlags( env['LIBIEC61883_FLAGS'] ) 
    3534    if not env['SERIALIZE_USE_EXPAT']: 
  • trunk/libffado/support/mixer/mixer_motu.py

    r1336 r1498  
    635635            self.mix4_dest.changeItem("AES/EBU", 7) 
    636636            self.phones_src.changeItem("AES/EBU", 7) 
     637 
     638        # The Ultralite doesn't have ADAT channels (or any optical ports at  
     639        # all) 
     640        if (self.model == MOTU_MODEL_ULTRALITE): 
     641            self.mix1_tab.page(3).setEnabled(False)  # ADAT page 
     642            self.mix2_tab.page(3).setEnabled(False)  # ADAT page 
     643            self.mix3_tab.page(3).setEnabled(False)  # ADAT page 
     644            self.mix4_tab.page(3).setEnabled(False)  # ADAT page 
     645            self.optical_in_mode.setEnabled(False) 
     646            self.optical_out_mode.setEnabled(False) 
    637647 
    638648        # Some devices don't have the option of selecting an optical SPDIF 
  • trunk/libffado/support/mixer/mixer_saffireprolarge.ui

    r1217 r1498  
    25452545                                                        </property> 
    25462546                                                        <property name="text"> 
    2547                                                             <string>IMixL</string> 
     2547                                                            <string>IMixR</string> 
    25482548                                                        </property> 
    25492549                                                        <property name="alignment"> 
     
    29772977                                                        </property> 
    29782978                                                        <property name="text"> 
    2979                                                             <string>IMixL</string> 
     2979                                                            <string>IMixR</string> 
    29802980                                                        </property> 
    29812981                                                        <property name="alignment"> 
     
    33603360                                                        </property> 
    33613361                                                        <property name="text"> 
    3362                                                             <string>IMixL</string> 
     3362                                                            <string>IMixR</string> 
    33633363                                                        </property> 
    33643364                                                        <property name="alignment"> 
     
    37323732                                                        </property> 
    37333733                                                        <property name="text"> 
    3734                                                             <string>IMixL</string> 
     3734                                                            <string>IMixR</string> 
    37353735                                                        </property> 
    37363736                                                        <property name="alignment"> 
     
    41534153                                                        </property> 
    41544154                                                        <property name="text"> 
    4155                                                             <string>IMixL</string> 
     4155                                                            <string>IMixR</string> 
    41564156                                                        </property> 
    41574157                                                        <property name="alignment"> 
  • trunk/libffado/support/mixer/mixer_saffireprosmall.ui

    r1217 r1498  
    263263                                                        </property> 
    264264                                                        <property name="text"> 
    265                                                             <string>IMixL</string> 
     265                                                            <string>IMixR</string> 
    266266                                                        </property> 
    267267                                                        <property name="alignment"> 
     
    695695                                                        </property> 
    696696                                                        <property name="text"> 
    697                                                             <string>IMixL</string> 
     697                                                            <string>IMixR</string> 
    698698                                                        </property> 
    699699                                                        <property name="alignment"> 
     
    10781078                                                        </property> 
    10791079                                                        <property name="text"> 
    1080                                                             <string>IMixL</string> 
     1080                                                            <string>IMixR</string> 
    10811081                                                        </property> 
    10821082                                                        <property name="alignment"> 
     
    14501450                                                        </property> 
    14511451                                                        <property name="text"> 
    1452                                                             <string>IMixL</string> 
     1452                                                            <string>IMixR</string> 
    14531453                                                        </property> 
    14541454                                                        <property name="alignment"> 
     
    18711871                                                        </property> 
    18721872                                                        <property name="text"> 
    1873                                                             <string>IMixL</string> 
     1873                                                            <string>IMixR</string> 
    18741874                                                        </property> 
    18751875                                                        <property name="alignment"> 
  • trunk/libffado/support/mixer/SConscript

    r1439 r1498  
    3535                       'saffirelelarge', 'saffirelesmall', 
    3636                       'audiofire_strip', 'audiofire_settings', 
    37                        'bcoaudio5', 
    38                        'edirolfa66','edirolfa101', 
     37                       'bcoaudio5', 'edirolfa66', 'edirolfa101', 
    3938                       'mackie_generic', 'quatafire', 'motu', 
    4039                       'global', 'dummy' 
     
    4544                       'saffirele', 
    4645                       'audiofire', 
    47                        'bcoaudio5', 
    48                        'edirolfa66','edirolfa101', 
     46                       'bcoaudio5', 'edirolfa66', 'edirolfa101', 
    4947                       'mackie_generic', 'quatafire', 'motu', 
    5048                       'global', 'dummy' 
  • trunk/libffado/support/SConscript

    r1336 r1498  
    2626env = env.Clone() 
    2727 
    28 env.SConscript( dirs=["mixer","mixer-qt4","firmware","dbus", "alsa"], exports="env" ) 
     28env.SConscript( dirs=["mixer","mixer-qt4","firmware","dbus","tools","alsa"], exports="env" ) 
  • trunk/libffado/tests/SConscript

    r1349 r1498  
    4444# 
    4545apps = { 
    46         "test-ffado" : "test-ffado.cpp", 
     46        "ffado-test" : "test-ffado.cpp", 
    4747        "test-fw410" : "test-fw410.cpp", 
    4848        "test-avccmd" : "test-avccmd.cpp", 
     
    7171for app in apps.keys(): 
    7272        env.Program( target=app, source = env.Split( apps[app] ) ) 
     73        env.Install( "$bindir", app ) 
    7374 
    7475env.SConscript( dirs=["streaming", "systemtests"], exports="env" ) 
  • trunk/libffado/tests/streaming/SConscript

    r1199 r1498  
    3030env.PrependUnique( LIBS=["ffado"] ) 
    3131 
    32 cppapps = "teststreaming3 teststreaming-ipc test-ipcclient" 
    3332 
    34 for app in env.Split( cppapps ): 
    35         env.Program( target=app, source = [ app+".cpp" ] ) 
     33apps = { 
     34        "ffado-test-streaming" : "teststreaming3.cpp", 
     35        "ffado-test-streaming-ipc" : "teststreaming-ipc.cpp", 
     36        "ffado-test-streaming-ipcclient" : "test-ipcclient.cpp", 
     37
    3638 
     39for app in apps.keys(): 
     40        env.Program( target=app, source = env.Split( apps[app] ) ) 
     41        env.Install( "$bindir", app ) 
    3742 
  • trunk/libffado/tests/systemtests/SConscript

    r1199 r1498  
    4040# 
    4141apps = { 
    42         "test-isorecv-1" : ["test-isorecv-1.cpp", "realtimetools.cpp"], 
    43         "test-isoxmit-1" : ["test-isoxmit-1.cpp", "realtimetools.cpp"], 
     42        "ffado-test-isorecv" : ["test-isorecv-1.cpp", "realtimetools.cpp"], 
     43        "ffado-test-isoxmit" : ["test-isoxmit-1.cpp", "realtimetools.cpp"], 
    4444        "test-sysload" : ["test-sysload.cpp", "realtimetools.cpp"], 
    4545        "gen-loadpulses" : ["gen-loadpulses.cpp", "realtimetools.cpp"], 
     
    4949for app in apps.keys(): 
    5050        env.Program( target=app, source = env.Split( apps[app] ) ) 
     51        env.Install( "$bindir", app ) 
    5152 
  • trunk/libffado/tests/test-ffado.cpp

    r1254 r1498  
    6767                    "           BusReset\n" 
    6868                    "           ListDevices\n" 
     69                    "           SetSplitTimeout timeout_usec\n" 
     70                    "           GetSplitTimeout\n" 
    6971                    ; 
    7072 
     
    238240    struct arguments arguments; 
    239241 
     242    printf("-----------------------------------------------\n"); 
     243    printf("FFADO test and diagnostic utility\n"); 
     244    printf("Part of the FFADO project -- www.ffado.org\n"); 
     245    printf("Version: %s\n", PACKAGE_VERSION); 
     246    printf("(C) 2008, Daniel Wagner, Pieter Palmers\n"); 
     247    printf("This program comes with ABSOLUTELY NO WARRANTY.\n"); 
     248    printf("-----------------------------------------------\n\n"); 
     249 
     250    // check the library version 
     251    const char *libversion = ffado_get_version(); 
     252    const char *progversion = PACKAGE_STRING; 
     253    if(strcmp(libversion, progversion) != 0) { 
     254        printf("Library version mismatch. (required: %s, present: %s)\n", progversion, libversion); 
     255        printf("Please run this application against the exact corresponding library\n"); 
     256        printf("it was compiled for. The most common cause for this is having more\n"); 
     257        printf("than one version of libffado installed.\n\n"); 
     258        return exitfunction(-1); 
     259    } 
     260 
    240261    // Default values. 
    241262    arguments.nargs       = 0; 
     
    255276        return exitfunction(-1); 
    256277    } 
    257  
    258     printf("verbose level = %ld\n", arguments.verbose); 
    259278    setDebugLevel(arguments.verbose); 
    260  
    261     printf( "Using ffado library version: %s\n\n", ffado_get_version() ); 
    262279 
    263280    if ( strcmp( arguments.args[0], "Discover" ) == 0 ) { 
     
    414431        delete m_deviceManager; 
    415432        return exitfunction(0); 
     433    } else if ( strcmp( arguments.args[0], "SetSplitTimeout" ) == 0 ) { 
     434        char* tail; 
     435        int usecs = strtol( arguments.args[1], &tail, 0 ); 
     436        if ( errno ) { 
     437            fprintf( stderr,  "Could not parse timeout argument\n" ); 
     438            return exitfunction(-1); 
     439        } 
     440 
     441        Ieee1394Service service; 
     442        // switch off all messages since they mess up the list 
     443        service.setVerboseLevel(arguments.verbose); 
     444        if ( !service.initialize( arguments.port ) ) { 
     445            printf("Could not initialize IEEE 1394 service on port %ld\n", arguments.port); 
     446            return exitfunction(-1); 
     447        } 
     448 
     449        nodeid_t nodeid; 
     450        if(arguments.node_id_set) { 
     451            nodeid = arguments.node_id; 
     452        } else { 
     453            nodeid = service.getLocalNodeId(); 
     454        } 
     455         
     456        if (!service.setSplitTimeoutUsecs(nodeid, usecs)) { 
     457            printf("Failed to set SPLIT_TIMEOUT to %u for node %X on port %ld\n", 
     458                   usecs, nodeid, arguments.port); 
     459            return exitfunction(-1); 
     460        } 
     461 
     462        return exitfunction(0); 
     463    } else if ( strcmp( arguments.args[0], "GetSplitTimeout" ) == 0 ) { 
     464        Ieee1394Service service; 
     465        // switch off all messages since they mess up the list 
     466        service.setVerboseLevel(arguments.verbose); 
     467        if ( !service.initialize( arguments.port ) ) { 
     468            printf("Could not initialize IEEE 1394 service on port %ld\n", arguments.port); 
     469            return exitfunction(-1); 
     470        } 
     471 
     472        nodeid_t nodeid; 
     473        if(arguments.node_id_set) { 
     474            nodeid = arguments.node_id; 
     475        } else { 
     476            nodeid = service.getLocalNodeId(); 
     477        } 
     478        int usecs = service.getSplitTimeoutUsecs(nodeid); 
     479        if (usecs < 0) { 
     480            printf("Failed to get SPLIT_TIMEOUT for node %X on port %ld\n", 
     481                   nodeid, arguments.port); 
     482            return exitfunction(-1); 
     483        } 
     484        printf("SPLIT_TIMEOUT for node %X on port %ld is %u\n", 
     485               nodeid, arguments.port, usecs); 
     486 
     487        return exitfunction(0); 
    416488    } else if ( strcmp( arguments.args[0], "SytCalcTest" ) == 0 ) { 
    417489        if (arguments.nargs < 4) { 
  • trunk/libffado/tests/test-ieee1394service.cpp

    r1135 r1498  
    8383        printf("hello from the functor (%p)\n", this); 
    8484    }; 
     85    virtual bool matchCallee(void *) {return false;}; 
    8586}; 
    8687