Changeset 734

Show
Ignore:
Timestamp:
11/28/07 05:03:31 (16 years ago)
Author:
ppalmers
Message:

merge ppalmers-streaming branch

Files:

Legend:

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

    r609 r734  
    1313 
    1414/* Define to the full name and version of this package. */ 
    15 #define PACKAGE_STRING "$PACKAGE $VERSION
     15#define PACKAGE_STRING "$PACKAGE $VERSION-$REVISION
    1616 
    1717/* Define to the one symbol short name of this package. */ 
     
    1919 
    2020/* Define to the version of this package. */ 
    21 #define PACKAGE_VERSION $VERSION 
     21#define PACKAGE_VERSION "$VERSION-$REVISION" 
    2222 
    2323/* Define to 1 if SSE assembly is available. */ 
    2424/*#define USE_SSE 1*/ 
    25  
    26 /* Version number of package */ 
    27 #define VERSION "$VERSION" 
    2825 
    2926#define CACHEDIR "~/.ffado" 
  • trunk/libffado/libffado/ffado.h

    r453 r734  
    145145typedef struct ffado_device_info { 
    146146    /* TODO: How is the device specification done? */ 
    147 //    char xml_location[FFADO_STREAMING_MAX_URL_LENGTH]; // can be an osc url or an XML filename 
    148147//    ffado_device_info_location_type location_type; 
    149148} ffado_device_info_t; 
  • trunk/libffado/SConstruct

    r718 r734  
    6262        buildenv['PKG_CONFIG_PATH']='' 
    6363 
    64 if os.environ.has_key('LD_LIBRARY_PATH'): 
    65         buildenv['LD_LIBRARY_PATH']=os.environ['LD_LIBRARY_PATH'] 
    66 else: 
    67         buildenv['LD_LIBRARY_PATH']='' 
    68  
    6964 
    7065env = Environment( tools=['default','scanreplace','pyuic','dbus','doxygen','pkgconfig'], toolpath=['admin'], ENV = buildenv, options=opts ) 
     
    9792opts.Save( 'cache/' + build_base + "options.cache", env ) 
    9893 
    99  
    100 tests = {} 
     94
     95# Check for apps... 
     96
     97def CheckForApp( context, app ): 
     98        context.Message( "Checking if '%s' executes... " % app ) 
     99        ret = context.env.WhereIs( app ) 
     100        if ret != "": 
     101                context.Result( True ) 
     102        else: 
     103                context.Result( False ) 
     104        return ret 
     105 
     106tests = { 'CheckForApp' : CheckForApp } 
    101107tests.update( env['PKGCONFIG_TESTS'] ) 
    102108 
     
    130136                'alsa' : '1.0.0', 
    131137                'libxml++-2.6' : '2.13.0', 
    132                 'liblo' : '0.22', 
    133138                'dbus-1' : '1.0', 
    134139                } 
     
    149154        # Optional checks follow: 
    150155        # 
     156        env['PYUIC'] = conf.CheckForApp( 'pyuic' ) 
    151157        env['ALSA_SEQ_OUTPUT'] = conf.CheckLib( 'asound', symbol='snd_seq_event_output_direct', autoadd=0 ) 
    152158 
     
    158164        env.AppendUnique( CCFLAGS=["-DDEBUG","-Wall","-g"] ) 
    159165else: 
    160         env.AppendUnique( CCFLAGS=["-O2"] ) 
     166        env.AppendUnique( CCFLAGS=["-O2","-DNDEBUG"] ) 
    161167 
    162168# this is required to indicate that the DBUS version we use has support 
     
    191197env['sharedir'] = Template( os.path.join( env['SHAREDIR'] ) ).safe_substitute( env ) 
    192198 
    193 env.Command( target=env['sharedir'], source="", action=Mkdir( env['sharedir'] ) ) 
    194  
    195199env.Alias( "install", env['libdir'] ) 
    196200env.Alias( "install", env['includedir'] ) 
     
    198202env.Alias( "install", env['bindir'] ) 
    199203 
     204 
     205env['REVISION'] = os.popen('svnversion .').read()[:-1] 
     206# This may be as simple as '89' or as complex as '4123:4184M'. 
     207# We'll just use the last bit. 
     208env['REVISION'] = env['REVISION'].split(':')[-1] 
     209 
     210if env['REVISION'] == 'exported': 
     211        env['REVISION'] = '' 
     212 
    200213env['PACKAGE'] = "libffado" 
    201 env['VERSION'] = "1.999.6
     214env['VERSION'] = "1.999.7
    202215env['LIBVERSION'] = "1.0.0" 
    203216 
     
    210223# Start building 
    211224# 
    212  
    213225env.ScanReplace( "config.h.in" ) 
    214226 
     
    222234        env.SConscript( dirs=subdirs, exports="env" ) 
    223235 
     236if 'debian' in COMMAND_LINE_TARGETS: 
     237        env.SConscript("deb/SConscript", exports="env") 
    224238 
    225239# By default only src is built but all is cleaned 
  • trunk/libffado/src/bebob/bebob_avdevice.h

    r661 r734  
    4242#include "bebob/bebob_mixer.h" 
    4343 
    44 #include "libstreaming/AmdtpStreamProcessor.h" 
    45 #include "libstreaming/AmdtpPort.h" 
    46 #include "libstreaming/AmdtpPortInfo.h" 
     44#include "libstreaming/amdtp/AmdtpReceiveStreamProcessor.h" 
     45#include "libstreaming/amdtp/AmdtpTransmitStreamProcessor.h" 
     46#include "libstreaming/amdtp/AmdtpPort.h" 
     47#include "libstreaming/amdtp/AmdtpPortInfo.h" 
    4748 
    4849#include "libutil/serialize.h" 
  • trunk/libffado/src/bebob/bebob_avdevice_subunit.cpp

    r716 r734  
    8282{ 
    8383    debugOutput(DEBUG_LEVEL_NORMAL, "Discovering %s...\n", getName()); 
    84  
     84     
    8585    // discover the AV/C generic part 
    8686    if ( !AVC::SubunitAudio::discover() ) { 
     
    160160#ifdef DEBUG 
    161161    if ((int)getDebugLevel() >= DEBUG_LEVEL_NORMAL) { 
    162  
     162     
    163163        for ( FunctionBlockVector::iterator it = m_functions.begin(); 
    164164            it != m_functions.end(); 
     
    340340bool 
    341341BeBoB::SubunitAudio::serializeChild( Glib::ustring basePath, 
    342                                      Util::IOSerialize& ser ) const 
     342                                             Util::IOSerialize& ser ) const 
    343343{ 
    344344    bool result = true; 
     
    363363bool 
    364364BeBoB::SubunitAudio::deserializeChild( Glib::ustring basePath, 
    365                                        Util::IODeserialize& deser, 
    366                                        AVC::Unit& avDevice ) 
     365                                               Util::IODeserialize& deser, 
     366                                               AVC::Unit& avDevice ) 
    367367{ 
    368368    int i = 0; 
     
    426426{ 
    427427    debugOutput(DEBUG_LEVEL_NORMAL, "Discovering %s...\n", getName()); 
    428  
     428     
    429429    // discover the AV/C generic part 
    430430    if ( !AVC::SubunitMusic::discover() ) { 
  • trunk/libffado/src/bebob/bebob_functionblock.cpp

    r716 r734  
    160160 
    161161bool 
     162serializePlugVector( Glib::ustring basePath, 
     163                       Util::IOSerialize& ser, 
     164                       const PlugVector& vec ) 
     165{ 
     166    bool result = true; 
     167    int i = 0; 
     168    for ( PlugVector::const_iterator it = vec.begin(); 
     169          it != vec.end(); 
     170          ++it ) 
     171    { 
     172        std::ostringstream strstrm; 
     173        strstrm << basePath << i; 
     174        result &= ser.write( strstrm.str(), ( *it )->getGlobalId() ); 
     175        i++; 
     176    } 
     177    return result; 
     178} 
     179 
     180bool 
     181deserializePlugVector( Glib::ustring basePath, 
     182                         Util::IODeserialize& deser, 
     183                         AVC::Unit& unit, 
     184                         PlugVector& vec ) 
     185{ 
     186    int i = 0; 
     187    bool bFinished = false; 
     188    bool result = true; 
     189    do { 
     190        plug_id_t plugId; 
     191        std::ostringstream strstrm; 
     192        strstrm << basePath << i; 
     193 
     194        if ( deser.isExisting( strstrm.str() ) ) { 
     195            result &= deser.read( strstrm.str(), plugId ); 
     196            AVC::Plug* pPlug = unit.getPlugManager().getPlug( plugId ); 
     197 
     198            if ( result && pPlug ) { 
     199                vec.push_back( pPlug ); 
     200                i++; 
     201            } else { 
     202                bFinished = true; 
     203            } 
     204        } else { 
     205            bFinished = true; 
     206        } 
     207    } while ( !bFinished ); 
     208 
     209    return result; 
     210} 
     211 
     212bool 
    162213FunctionBlock::serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const 
    163214{ 
     
    178229FunctionBlock* 
    179230FunctionBlock::deserialize( Glib::ustring basePath, 
    180                             Util::IODeserialize& deser, 
    181                             AVC::Unit& unit, 
    182                             AVC::Subunit& subunit ) 
     231                                   Util::IODeserialize& deser, 
     232                                   AVC::Unit& unit, 
     233                                   AVC::Subunit& subunit ) 
    183234{ 
    184235    bool result; 
     
    227278    result &= deser.read( basePath + "m_nrOfOutputPlugs", pFB->m_nrOfOutputPlugs ); 
    228279    result &= deser.read( basePath + "m_verbose", pFB->m_verbose ); 
    229     result &= deserializePlugVector( basePath + "m_plugs", deser, 
    230                                      unit.getPlugManager(), pFB->m_plugs ); 
     280    result &= deserializePlugVector( basePath + "m_plugs", deser, unit, pFB->m_plugs ); 
    231281 
    232282    return 0; 
  • trunk/libffado/src/bebob/bebob_functionblock.h

    r716 r734  
    6969 
    7070    virtual const char* getName() = 0; 
    71  
     71     
    7272    AVC::function_block_type_t getType() {return m_type;}; 
    7373    AVC::function_block_type_t getSubtype() {return m_subtype;}; 
    7474    AVC::function_block_id_t getId() {return m_id;}; 
    75  
     75     
    7676    AVC::no_of_input_plugs_t getNrOfInputPlugs() {return m_nrOfInputPlugs;}; 
    7777    AVC::no_of_output_plugs_t getNrOfOutputPlugs() {return m_nrOfOutputPlugs;}; 
    7878 
    7979    bool serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const; 
    80  
    8180    static FunctionBlock* deserialize( Glib::ustring basePath, 
    8281                       Util::IODeserialize& deser, 
     
    145144 
    146145    virtual const char* getName(); 
    147  
     146     
    148147    // FIXME: this is not pretty! 
    149148    enum EControlSelectorEncoding { 
  • trunk/libffado/src/bounce/bounce_avdevice.h

    r639 r734  
    3030#include "libavc/general/avc_extended_cmd_generic.h" 
    3131 
    32 #include "libstreaming/AmdtpStreamProcessor.h" 
    33 #include "libstreaming/AmdtpPort.h" 
    34 #include "libstreaming/AmdtpPortInfo.h" 
     32#include "libstreaming/amdtp/AmdtpReceiveStreamProcessor.h" 
     33#include "libstreaming/amdtp/AmdtpTransmitStreamProcessor.h" 
     34#include "libstreaming/amdtp/AmdtpPort.h" 
     35#include "libstreaming/amdtp/AmdtpPortInfo.h" 
    3536 
    3637#include "libieee1394/ARMHandler.h" 
  • trunk/libffado/src/bounce/bounce_slave_avdevice.cpp

    r587 r734  
    2323 */ 
    2424 
    25 #include "libstreaming/AmdtpSlaveStreamProcessor.h" 
     25#include "libstreaming/amdtp/AmdtpSlaveStreamProcessor.h" 
    2626 
    2727#include "libieee1394/configrom.h" 
  • trunk/libffado/src/debugmodule/debugmodule.cpp

    r698 r734  
    3535 
    3636#ifndef DO_MESSAGE_BUFFER_PRINT 
    37        #warning Printing debug info without ringbuffer, not RT-safe! 
     37    #warning Printing debug info without ringbuffer, not RT-safe! 
    3838#endif 
    3939 
     
    4646 
    4747ColorEntry colorTable[] = { 
     48    { "",           ""        }, 
    4849    { "\033[31mFatal",   "\033[0m" }, 
    4950    { "\033[31mError",   "\033[0m" }, 
     
    213214DebugModule::getPreSequence( debug_level_t level ) const 
    214215{ 
    215     if ( ( level <= eDL_Normal ) && ( level >= eDL_Fatal ) ) { 
     216    if ( ( level <= eDL_Normal ) && ( level >= eDL_Message ) ) { 
    216217        return colorTable[level].preSequence; 
    217218    } 
     
    222223DebugModule::getPostSequence( debug_level_t level ) const 
    223224{ 
    224     if ( ( level <= eDL_Normal ) && ( level >= eDL_Fatal ) ) { 
     225    if ( ( level <= eDL_Normal ) && ( level >= eDL_Message ) ) { 
    225226        return colorTable[level].postSequence; 
    226227    } 
     
    428429    for (unsigned int i=0; i<BACKLOG_MB_BUFFERS;i++) { 
    429430        unsigned int idx=(i+bl_mb_inbuffer)%BACKLOG_MB_BUFFERS; 
     431        fputs("BL: ", stderr); 
    430432        fputs(bl_mb_buffers[idx], stderr); 
    431433    } 
    432     fprintf(stderr, "\n"); 
     434    fprintf(stderr, "BL: \n"); 
    433435 
    434436    fprintf(stderr, "=====================================================\n"); 
     
    454456        if (lines_to_skip-- < 0) { 
    455457            unsigned int idx=(i+bl_mb_inbuffer)%BACKLOG_MB_BUFFERS; 
     458            fputs("BL: ", stderr); 
    456459            fputs(bl_mb_buffers[idx], stderr); 
    457460        } 
    458461    } 
    459     fprintf(stderr, "\n"); 
     462    fprintf(stderr, "BL: \n"); 
    460463 
    461464    fprintf(stderr, "=====================================================\n"); 
  • trunk/libffado/src/debugmodule/debugmodule.h

    r698 r734  
    3434typedef short debug_level_t; 
    3535 
    36 #define DEBUG_LEVEL_FATAL          0 
    37 #define DEBUG_LEVEL_ERROR          1 
    38 #define DEBUG_LEVEL_WARNING        2 
    39 #define DEBUG_LEVEL_NORMAL         3 
    40 #define DEBUG_LEVEL_INFO           4 
    41 #define DEBUG_LEVEL_VERBOSE        5 
    42 #define DEBUG_LEVEL_VERY_VERBOSE   6 
    43 #define DEBUG_LEVEL_ULTRA_VERBOSE  7 
     36#define DEBUG_LEVEL_MESSAGE        0 
     37#define DEBUG_LEVEL_FATAL          1 
     38#define DEBUG_LEVEL_ERROR          2 
     39#define DEBUG_LEVEL_WARNING        3 
     40#define DEBUG_LEVEL_NORMAL         4 
     41#define DEBUG_LEVEL_INFO           5 
     42#define DEBUG_LEVEL_VERBOSE        6 
     43#define DEBUG_LEVEL_VERY_VERBOSE   7 
     44#define DEBUG_LEVEL_ULTRA_VERBOSE  8 
    4445 
    4546#define DEBUG_MAX_MESSAGE_LENGTH 512 
     
    9596                                     ##args ) 
    9697 
     98// these are for messages that are also displayed when not compiled 
     99// for debug 
     100#define printMessage( format, args... )                             \ 
     101                m_debugModule.print( DebugModule::eDL_Message,      \ 
     102                                     __FILE__,                      \ 
     103                                     __FUNCTION__,                  \ 
     104                                     __LINE__,                      \ 
     105                                    format,                         \ 
     106                                    ##args ) 
     107#define printMessageShort( format, args... )                        \ 
     108                m_debugModule.printShort( DebugModule::eDL_Message, \ 
     109                                     format,                        \ 
     110                                     ##args ) 
     111 
    97112#define DECLARE_DEBUG_MODULE static DebugModule m_debugModule 
    98113#define IMPL_DEBUG_MODULE( ClassName, RegisterName, Level )        \ 
     
    182197public: 
    183198    enum { 
     199        eDL_Message      = DEBUG_LEVEL_MESSAGE, 
    184200        eDL_Fatal        = DEBUG_LEVEL_FATAL, 
    185201        eDL_Error        = DEBUG_LEVEL_ERROR, 
  • trunk/libffado/src/devicemanager.cpp

    r674 r734  
    3131#include "libieee1394/ieee1394service.h" 
    3232 
    33 #include "libstreaming/StreamProcessor.h" 
     33#include "libstreaming/generic/StreamProcessor.h" 
    3434 
    3535#include "debugmodule/debugmodule.h" 
  • trunk/libffado/src/devicemanager.h

    r674 r734  
    3232 
    3333#include "libutil/OptionContainer.h" 
    34 // #include "libosc/OscServer.h" 
    35 // #include "libosc/OscNode.h" 
    3634#include "libcontrol/BasicElements.h" 
    3735 
  • trunk/libffado/src/dice/dice_avdevice.cpp

    r672 r734  
    2828#include "libieee1394/ieee1394service.h" 
    2929 
    30 #include "libstreaming/AmdtpStreamProcessor.h" 
    31  
    3230#include "debugmodule/debugmodule.h" 
    3331 
     
    5149    // vendor id, model id, vendor name, model name 
    5250    {FW_VENDORID_TCAT, 0x00000002, "TCAT", "DiceII EVM"}, 
     51    {FW_VENDORID_TCAT, 0x00000004, "TCAT", "DiceII EVM (vxx)"}, 
    5352}; 
    5453 
     
    448447bool 
    449448DiceAvDevice::prepare() { 
    450     int samplerate=getSamplingFrequency(); 
    451  
    452449    // prepare receive SP's 
    453450    for (unsigned int i=0;i<m_nb_tx;i++) { 
     
    494491        p=new Streaming::AmdtpReceiveStreamProcessor( 
    495492                             m_p1394Service->getPort(), 
    496                              samplerate, 
    497493                             nb_channels); 
    498494 
     
    581577        p=new Streaming::AmdtpTransmitStreamProcessor( 
    582578                             m_p1394Service->getPort(), 
    583                              samplerate, 
    584579                             nb_channels); 
    585580 
  • trunk/libffado/src/dice/dice_avdevice.h

    r639 r734  
    3030#include "libavc/avc_definitions.h" 
    3131 
    32 #include "libstreaming/AmdtpStreamProcessor.h" 
    33 #include "libstreaming/AmdtpPort.h" 
     32#include "libstreaming/amdtp/AmdtpReceiveStreamProcessor.h" 
     33#include "libstreaming/amdtp/AmdtpTransmitStreamProcessor.h" 
     34#include "libstreaming/amdtp/AmdtpPort.h" 
    3435#include "libieee1394/ARMHandler.h" 
    3536 
  • trunk/libffado/src/ffadodevice.cpp

    r674 r734  
    118118 
    119119    retval=setOption("id",idstr.str()); 
    120 /*    if (retval) { 
    121         setOscBase(idstr.str()); 
    122     }*/ 
    123120    return retval; 
    124121} 
  • trunk/libffado/src/ffado_streaming.cpp

    r554 r734  
    7676    } 
    7777 
    78     dev->m_deviceManager->setVerboseLevel(DEBUG_LEVEL_VERBOSE); 
     78    dev->m_deviceManager->setVerboseLevel(DEBUG_LEVEL_NORMAL); 
    7979    if ( !dev->m_deviceManager->initialize( dev->options.port ) ) { 
    8080            debugFatal( "Could not initialize device manager\n" ); 
     
    8686    // create a processor manager to manage the actual stream 
    8787    // processors 
    88     dev->processorManager = new StreamProcessorManager(dev->options.period_size,dev->options.nb_buffers); 
     88    dev->processorManager = new StreamProcessorManager( dev->options.period_size,  
     89                                                        dev->options.sample_rate, 
     90                                                        dev->options.nb_buffers); 
    8991    if(!dev->processorManager) { 
    9092            debugFatal("Could not create StreamProcessorManager\n"); 
     
    170172        // prepare the device 
    171173        device->prepare(); 
    172  
    173174        int j=0; 
    174175        for(j=0; j<device->getStreamCount();j++) { 
     
    176177            debugOutput(DEBUG_LEVEL_VERBOSE, "Registering stream processor %d of device %d with processormanager\n",j,i); 
    177178            if (!dev->processorManager->registerProcessor(streamproc)) { 
    178                 debugWarning("Could not register stream processor (%p) with the Processor manager\n",streamproc); 
     179                delete dev->processorManager; 
     180                delete dev->m_deviceManager; 
     181                delete dev; 
     182                debugFatal("Could not register stream processor (%p) with the Processor manager\n", streamproc); 
     183                return 0; 
    179184            } 
    180185        } 
     
    331336 
    332337int ffado_streaming_transfer_capture_buffers(ffado_device_t *dev) { 
    333     return dev->processorManager->transfer(StreamProcessor::E_Receive); 
     338    return dev->processorManager->transfer(StreamProcessor::ePT_Receive); 
    334339} 
    335340 
    336341int ffado_streaming_transfer_playback_buffers(ffado_device_t *dev) { 
    337     return dev->processorManager->transfer(StreamProcessor::E_Transmit); 
     342    return dev->processorManager->transfer(StreamProcessor::ePT_Transmit); 
    338343} 
    339344 
  • trunk/libffado/src/genericavc/avc_avdevice.cpp

    r716 r734  
    236236        bool found=false; 
    237237        for ( PlugVector::const_iterator it2 = syncMSUInputPlugs.begin(); 
    238               it2 != syncMSUInputPlugs.end(); 
    239               ++it2 ) 
     238            it2 != syncMSUInputPlugs.end(); 
     239            ++it2 ) 
    240240        { 
    241241            AVC::Plug* msuPlug = *it2; 
     
    422422    } 
    423423 
    424     int samplerate=outputPlug->getSampleRate(); 
    425  
    426424    debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing receive processor...\n"); 
    427425    // create & add streamprocessors 
    428426    Streaming::StreamProcessor *p; 
    429427 
     428    if ( outputPlug->getNrOfChannels() == 0 ) { 
     429        debugError("Receive plug has no channels\n"); 
     430        return false; 
     431    } 
    430432    p=new Streaming::AmdtpReceiveStreamProcessor( 
    431433                             get1394Service().getPort(), 
    432                              samplerate, 
    433434                             outputPlug->getNrOfChannels()); 
    434435 
     
    455456        p=new Streaming::AmdtpReceiveStreamProcessor( 
    456457                                  get1394Service().getPort(), 
    457                                   samplerate, 
    458458                                  inputPlug->getNrOfChannels()); 
    459459    } else { 
    460460        p=new Streaming::AmdtpTransmitStreamProcessor( 
    461461                                get1394Service().getPort(), 
    462                                 samplerate, 
    463462                                inputPlug->getNrOfChannels()); 
    464463    } 
     
    596595AvDevice::getStreamCount() { 
    597596    return m_receiveProcessors.size() + m_transmitProcessors.size(); 
     597    //return 1; 
    598598} 
    599599 
  • trunk/libffado/src/genericavc/avc_avdevice.h

    r639 r734  
    3434#include "libavc/general/avc_plug.h" 
    3535 
    36 #include "libstreaming/AmdtpStreamProcessor.h" 
    37 #include "libstreaming/AmdtpPort.h" 
    38 #include "libstreaming/AmdtpPortInfo.h" 
     36#include "libstreaming/amdtp/AmdtpReceiveStreamProcessor.h" 
     37#include "libstreaming/amdtp/AmdtpTransmitStreamProcessor.h" 
     38#include "libstreaming/amdtp/AmdtpPort.h" 
     39#include "libstreaming/amdtp/AmdtpPortInfo.h" 
    3940 
    4041#include "debugmodule/debugmodule.h" 
  • trunk/libffado/src/libavc/audiosubunit/avc_audiosubunit.h

    r716 r734  
    5252protected: 
    5353    virtual bool serializeChild( Glib::ustring basePath, 
    54                                  Util::IOSerialize& ser ) const { return true; } 
     54                                 Util::IOSerialize& ser ) const {return false;}; 
    5555    virtual bool deserializeChild( Glib::ustring basePath, 
    5656                                   Util::IODeserialize& deser, 
    57                                    Unit& avDevice ) { return true; } 
     57                                   Unit& avDevice ) {return false;}; 
    5858 
    5959}; 
  • trunk/libffado/src/libavc/descriptors/avc_descriptor.cpp

    r626 r734  
    146146AVCDescriptor::reload() 
    147147{ 
    148     m_loaded=false; 
     148    m_loaded = false; 
    149149    return load(); 
    150150} 
     
    178178    } 
    179179     
    180     debugOutput(DEBUG_LEVEL_VERBOSE, " Read status descriptor\n"); 
     180    debugOutput(DEBUG_LEVEL_VERBOSE, " Read descriptor\n"); 
    181181    ReadDescriptorCmd readDescCmd(m_unit->get1394Service()); 
    182182    readDescCmd.m_specifier=&m_specifier; 
     
    199199    if (bytes_read < 2) { 
    200200        debugOutput(DEBUG_LEVEL_VERBOSE, " Descriptor length field not present\n"); 
    201         return false;         
    202     } 
    203      
     201        return false; 
     202    } 
     203 
     204#ifdef DEBUG 
     205    if(getDebugLevel() >= DEBUG_LEVEL_VERY_VERBOSE) { 
     206        debugOutput(DEBUG_LEVEL_VERBOSE, " Read result:\n"); 
     207        printBufferBytes( DEBUG_LEVEL_VERY_VERBOSE, bytes_read, readDescCmd.m_data ); 
     208    } 
     209#endif 
     210 
    204211    // obtain descriptor length 
    205212    m_descriptor_length=(readDescCmd.m_data[0]<<8) + (readDescCmd.m_data[1]); 
     
    274281        return false; 
    275282    } 
    276  
     283#ifdef DEBUG 
     284    if(getDebugLevel() >= DEBUG_LEVEL_VERY_VERBOSE) { 
     285        debugOutput(DEBUG_LEVEL_VERBOSE, " Descriptor content:\n"); 
     286        printBufferBytes( DEBUG_LEVEL_VERY_VERBOSE, m_descriptor_length, m_data ); 
     287    } 
     288#endif 
    277289    debugOutput(DEBUG_LEVEL_VERBOSE, " Parse descriptor\n"); 
    278290    // parse the descriptor 
     
    347359} 
    348360 
     361void 
     362AVCDescriptor::printBufferBytes( unsigned int level, size_t length, byte_t* buffer ) const 
     363{ 
     364 
     365    for ( unsigned int i=0; i < length; ++i ) { 
     366        if ( ( i % 16 ) == 0 ) { 
     367            if ( i > 0 ) { 
     368                debugOutputShort(level,"\n"); 
     369            } 
     370            debugOutputShort(level," %4d: ",i*16); 
     371        } 
     372        debugOutputShort(level,"%02X ",buffer[i]); 
     373    } 
     374    debugOutputShort(level,"\n"); 
     375} 
     376 
    349377// --- Info block 
    350378AVCInfoBlock::AVCInfoBlock( ) 
  • trunk/libffado/src/libavc/descriptors/avc_descriptor.h

    r618 r734  
    137137     
    138138protected: 
     139    void printBufferBytes(unsigned int level, size_t length, byte_t* buffer) const; 
    139140 
    140141    Unit*            m_unit; 
  • trunk/libffado/src/libavc/descriptors/avc_descriptor_cmd.cpp

    r618 r734  
    179179        return false; 
    180180    } 
    181     return true;     
    182181    return true; 
    183182} 
  • trunk/libffado/src/libavc/general/avc_plug.cpp

    r716 r734  
    15761576} 
    15771577 
     1578 
     1579bool 
     1580Plug::serializePlugVector( Glib::ustring basePath, 
     1581                           Util::IOSerialize& ser, 
     1582                           const PlugVector& vec) const 
     1583{ 
     1584    bool result = true; 
     1585    int i = 0; 
     1586    for ( PlugVector::const_iterator it = vec.begin(); 
     1587          it != vec.end(); 
     1588          ++it ) 
     1589    { 
     1590        const Plug* pPlug = *it; 
     1591        std::ostringstream strstrm; 
     1592        strstrm << basePath << i; 
     1593 
     1594        result &= ser.write( strstrm.str() + "/global_id", pPlug->getGlobalId() ); 
     1595        i++; 
     1596    } 
     1597    return result; 
     1598} 
     1599 
     1600bool 
     1601Plug::deserializePlugVector( Glib::ustring basePath, 
     1602                             Util::IODeserialize& deser, 
     1603                             PlugVector& vec ) 
     1604{ 
     1605    int i = 0; 
     1606    bool bFinished = false; 
     1607    bool result = true; 
     1608    do { 
     1609        std::ostringstream strstrm; 
     1610        strstrm << basePath << i; 
     1611 
     1612        // check for one element to exist. when one exist the other elements 
     1613        // must also be there. otherwise just return (last) result. 
     1614        if ( deser.isExisting( strstrm.str() + "/global_id" ) ) { 
     1615            unsigned int iPlugId; 
     1616            result &= deser.read( strstrm.str() + "/global_id", iPlugId ); 
     1617 
     1618            if ( result ) { 
     1619                Plug* pPlug = m_unit->getPlugManager().getPlug( iPlugId ); 
     1620                if ( pPlug ) { 
     1621                    vec.push_back( pPlug ); 
     1622                } else { 
     1623                    result = false; 
     1624                    bFinished = true; 
     1625                } 
     1626                i++; 
     1627            } else { 
     1628                bFinished = true; 
     1629            } 
     1630        } else { 
     1631            bFinished = true; 
     1632        } 
     1633    } while ( !bFinished ); 
     1634 
     1635    return result; 
     1636} 
     1637 
    15781638bool 
    15791639Plug::serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const 
     
    16231683    bool result=true; 
    16241684 
    1625     result  = deser.read( basePath + "m_subunitType", pPlug->m_subunitType ); 
    1626     result &= deser.read( basePath + "m_subunitId", pPlug->m_subunitId ); 
     1685    ESubunitType subunitType; 
     1686    result  = deser.read( basePath + "m_subunitType", subunitType ); 
     1687    subunit_t subunitId; 
     1688    result &= deser.read( basePath + "m_subunitId", subunitId ); 
     1689    pPlug->m_subunit = unit.getSubunit( subunitType, subunitType ); 
     1690 
    16271691    result &= deser.read( basePath + "m_functionBlockType", pPlug->m_functionBlockType ); 
    16281692    result &= deser.read( basePath + "m_functionBlockId", pPlug->m_functionBlockId ); 
     
    16541718bool 
    16551719Plug::deserializeUpdate( Glib::ustring basePath, 
    1656                          Util::IODeserialize& deser ) 
     1720                           Util::IODeserialize& deser ) 
    16571721{ 
    16581722    bool result; 
    16591723 
    1660     result  = deserializePlugVector( basePath + "m_inputConnections", deser, 
    1661                                      m_unit->getPlugManager(), m_inputConnections ); 
    1662     result &= deserializePlugVector( basePath + "m_outputConnections", deser, 
    1663                                      m_unit->getPlugManager(), m_outputConnections ); 
     1724    result  = deserializePlugVector( basePath + "m_inputConnections", deser, m_inputConnections ); 
     1725    result &= deserializePlugVector( basePath + "m_outputConnections", deser, m_outputConnections ); 
    16641726 
    16651727    return result; 
    1666 } 
    1667  
    1668 bool 
    1669 Plug::deserializeUpdateSubunit() 
    1670 { 
    1671     m_subunit = m_unit->getSubunit( m_subunitType, m_subunitId ); 
    1672     return true; 
    16731728} 
    16741729 
     
    21502205} 
    21512206 
    2152 bool 
    2153 PlugManager::deserializeUpdate() 
    2154 { 
    2155     bool result = true; 
    2156  
    2157     for ( PlugVector::const_iterator it = m_plugs.begin(); 
    2158           it !=  m_plugs.end(); 
    2159           ++it ) 
    2160     { 
    2161         Plug* pPlug = *it; 
    2162  
    2163         result &= pPlug->deserializeUpdateSubunit(); 
    2164     } 
    2165  
    2166     return result; 
    2167 } 
    21682207 
    21692208//////////////////////////////////// 
     
    23002339} 
    23012340 
    2302 bool 
    2303 serializePlugVector( Glib::ustring basePath, 
    2304                      Util::IOSerialize& ser, 
    2305                      const PlugVector& vec) 
    2306 
    2307     bool result = true; 
    2308     int i = 0; 
    2309     for ( PlugVector::const_iterator it = vec.begin(); 
    2310           it != vec.end(); 
    2311           ++it ) 
    2312     { 
    2313         const Plug* pPlug = *it; 
    2314         std::ostringstream strstrm; 
    2315         strstrm << basePath << i; 
    2316  
    2317         result &= ser.write( strstrm.str() + "/global_id", pPlug->getGlobalId() ); 
    2318         i++; 
    2319     } 
    2320     return result; 
    2321 
    2322  
    2323 bool 
    2324 deserializePlugVector( Glib::ustring basePath, 
    2325                        Util::IODeserialize& deser, 
    2326                        const PlugManager& plugManager, 
    2327                        PlugVector& vec ) 
    2328 
    2329     int i = 0; 
    2330     bool bFinished = false; 
    2331     bool result = true; 
    2332     do { 
    2333         std::ostringstream strstrm; 
    2334         strstrm << basePath << i; 
    2335  
    2336         // check for one element to exist. when one exist the other elements 
    2337         // must also be there. otherwise just return (last) result. 
    2338         if ( deser.isExisting( strstrm.str() + "/global_id" ) ) { 
    2339             unsigned int iPlugId; 
    2340             result &= deser.read( strstrm.str() + "/global_id", iPlugId ); 
    2341  
    2342             if ( result ) { 
    2343                 Plug* pPlug = plugManager.getPlug( iPlugId ); 
    2344                 if ( pPlug ) { 
    2345                     vec.push_back( pPlug ); 
    2346                 } else { 
    2347                     result = false; 
    2348                     bFinished = true; 
    2349                 } 
    2350                 i++; 
    2351             } else { 
    2352                 bFinished = true; 
    2353             } 
    2354         } else { 
    2355             bFinished = true; 
    2356         } 
    2357     } while ( !bFinished ); 
    2358  
    2359     return result; 
    2360 
    2361  
    2362 
     2341
  • trunk/libffado/src/libavc/general/avc_plug.h

    r716 r734  
    163163    bool deserializeUpdate( Glib::ustring basePath, 
    164164                            Util::IODeserialize& deser ); 
    165     bool deserializeUpdateSubunit(); 
    166165 
    167166 public: 
     
    257256    bool deserializeFormatInfos( Glib::ustring basePath, 
    258257                                 Util::IODeserialize& deser ); 
     258 
     259    bool serializePlugVector( Glib::ustring basePath, 
     260                              Util::IOSerialize& ser, 
     261                              const PlugVector& vec) const; 
     262    bool deserializePlugVector( Glib::ustring basePath, 
     263                                Util::IODeserialize& deser, 
     264                                PlugVector& vec ); 
    259265 
    260266protected: 
     
    279285    Unit*                       m_unit; 
    280286    Subunit*                    m_subunit; 
    281     ESubunitType                m_subunitType; 
    282     subunit_t                   m_subunitId; 
    283287    function_block_type_t       m_functionBlockType; 
    284288    function_block_id_t         m_functionBlockId; 
     
    345349    bool tidyPlugConnections(PlugConnectionVector&); 
    346350 
    347     bool deserializeUpdate(); 
    348  
    349351private: 
    350352 
     
    377379typedef std::vector<PlugConnection> PlugConnectionOwnerVector; 
    378380 
    379  
    380 bool serializePlugVector( Glib::ustring basePath, 
    381                           Util::IOSerialize& ser, 
    382                           const PlugVector& vec); 
    383  
    384 bool deserializePlugVector( Glib::ustring basePath, 
    385                             Util::IODeserialize& deser, 
    386                             const PlugManager& plugManager, 
    387                             PlugVector& vec ); 
    388  
    389381} 
    390382 
  • trunk/libffado/src/libavc/general/avc_subunit.cpp

    r716 r734  
    107107{ 
    108108    debugOutput(DEBUG_LEVEL_NORMAL, "Discovering plugs...\n"); 
    109  
     109     
    110110    PlugInfoCmd plugInfoCmd( getUnit().get1394Service(), 
    111111                             PlugInfoCmd::eSF_SerialBusIsochronousAndExternalPlug ); 
     
    147147{ 
    148148    debugOutput(DEBUG_LEVEL_NORMAL, "Discovering connections...\n"); 
    149  
     149     
    150150    for ( PlugVector::iterator it = getPlugs().begin(); 
    151151          it != getPlugs().end(); 
     
    183183            return false; 
    184184        } 
    185  
     185         
    186186        plug->setVerboseLevel(getDebugLevel()); 
    187  
     187         
    188188        if ( !plug->discover() ) { 
    189189            debugError( "plug discover failed\n" ); 
     
    232232bool 
    233233Subunit::serialize( Glib::ustring basePath, 
    234                     Util::IOSerialize& ser ) const 
     234                                   Util::IOSerialize& ser ) const 
    235235{ 
    236236    bool result; 
     
    239239    result &= ser.write( basePath + "m_sbId", m_sbId ); 
    240240    result &= ser.write( basePath + "m_verboseLevel", getDebugLevel() ); 
    241     result &= serializePlugVector( basePath + "m_plugs", ser, m_plugs ); 
    242241    result &= serializeChild( basePath, ser ); 
    243242 
     
    260259 
    261260    Subunit* pSubunit = 0; 
    262  
     261     
    263262    #warning FIXME: The derived class should be creating these 
    264263    // FIXME: The derived class should be creating these, such that discover() can become pure virtual 
     
    281280    pSubunit->m_sbType = sbType; 
    282281    result &= deser.read( basePath + "m_sbId", pSubunit->m_sbId ); 
    283     result &= deserializePlugVector( basePath + "m_plugs", deser, 
    284                                      unit.getPlugManager(), pSubunit->m_plugs ); 
    285282    int verboseLevel; 
    286283    result &= deser.read( basePath + "m_verboseLevel", verboseLevel ); 
  • trunk/libffado/src/libavc/general/avc_subunit.h

    r716 r734  
    7373 
    7474    PlugVector& getPlugs() 
    75        { return m_plugs; } 
     75    { return m_plugs; } 
    7676    Plug* getPlug(Plug::EPlugDirection direction, plug_id_t plugId); 
    7777 
     
    8080    bool serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const; 
    8181    static Subunit* deserialize( Glib::ustring basePath, 
    82                                 Util::IODeserialize& deser, Unit& avDevice ); 
     82                    Util::IODeserialize& deser, Unit& avDevice ); 
    8383 protected: 
    8484    Subunit(); 
  • trunk/libffado/src/libavc/general/avc_unit.cpp

    r716 r734  
    975975    result  = ser.write( basePath + "m_verboseLevel_unit", getDebugLevel() ); 
    976976    result &= serializeVector( basePath + "Subunit", ser, m_subunits ); 
    977     result &= serializePlugVector( basePath + "PcrPlug", ser, m_pcrPlugs ); 
    978     result &= serializePlugVector( basePath + "ExternalPlug",  ser, m_externalPlugs ); 
     977    result &= serializeVector( basePath + "PcrPlug", ser, m_pcrPlugs ); 
     978    result &= serializeVector( basePath + "ExternalPlug",  ser, m_externalPlugs ); 
    979979    result &= serializeVector( basePath + "PlugConnection", ser, m_plugConnections ); 
    980980    result &= m_pPlugManager->serialize( basePath + "Plug", ser ); // serialize all av plugs 
     
    10071007    setDebugLevel( verboseLevel ); 
    10081008 
    1009     result &= deserializeVector<Subunit>( basePath + "Subunit", deser, *this, m_subunits ); 
     1009    result &= deserializeVector<Subunit>( basePath + "Subunit", deser, *this, m_subunits ); 
    10101010 
    10111011    if (m_pPlugManager) 
     
    10171017        return false; 
    10181018 
    1019     result &= deserializePlugVector( basePath + "PcrPlug", deser, getPlugManager(), m_pcrPlugs ); 
    1020     result &= deserializePlugVector( basePath + "ExternalPlug", deser, getPlugManager(), m_externalPlugs ); 
     1019    // XXX We have to deserialize the m_pcrPlugs and m_externPlugs members somehow. 
     1020    // Of course the simple following simple approach wont work at the moment. Some 
     1021    // more hacking needed :) 
     1022    //result &= deserializeVector<Plug>( basePath + "PcrPlug", deser, *this, m_pcrPlugs ); 
     1023    //result &= deserializeVector<Plug>( basePath + "ExternalPlug", deser, *this, m_externalPlugs ); 
     1024    result &= deserializePlugUpdateConnections( basePath + "PcrPlug", deser, m_pcrPlugs ); 
     1025    result &= deserializePlugUpdateConnections( basePath + "ExternalPlug", deser, m_externalPlugs ); 
    10211026    result &= deserializeVector<PlugConnection>( basePath + "PlugConnnection", deser, *this, m_plugConnections ); 
    10221027    result &= deserializeVector<Subunit>( basePath + "Subunit",  deser, *this, m_subunits ); 
    10231028    result &= deserializeSyncInfoVector( basePath + "SyncInfo", deser, m_syncInfos ); 
    10241029 
    1025     result &= deserializePlugUpdateConnections( basePath + "PcrPlug", deser, m_pcrPlugs ); 
    1026     result &= deserializePlugUpdateConnections( basePath + "ExternalPlug", deser, m_externalPlugs ); 
    1027     m_pPlugManager->deserializeUpdate(); 
    1028  
    10291030    unsigned int i; 
    10301031    result &= deser.read( basePath + "m_activeSyncInfo", i ); 
  • trunk/libffado/src/libavc/musicsubunit/avc_musicsubunit.cpp

    r716 r734  
    6363{ 
    6464    debugOutput(DEBUG_LEVEL_NORMAL, "Discovering %s...\n", getName()); 
    65  
     65     
    6666    // discover the AV/C generic part 
    6767    if ( !Subunit::discover() ) { 
    6868        return false; 
    6969    } 
    70  
     70     
    7171    // now we have the subunit plugs 
    72  
     72     
    7373    return true; 
    7474} 
     
    7979    debugOutput(DEBUG_LEVEL_VERBOSE, "Loading info from descriptor for plug: \n"); 
    8080    bool result=true; 
    81  
     81     
    8282    // load the descriptor (if not already loaded) 
    8383    if (m_status_descriptor != NULL) { 
    8484        result &= m_status_descriptor->load(); 
    8585    } 
    86  
     86     
    8787    AVCMusicSubunitPlugInfoBlock *info; 
    8888    info = m_status_descriptor->getSubunitPlugInfoBlock(plug.getDirection(), plug.getPlugId()); 
    89  
     89     
    9090    if (info == NULL) { 
    9191        debugError("Could not find plug info block\n"); 
    9292        return false; 
    9393    } 
    94  
     94     
    9595    debugOutput(DEBUG_LEVEL_VERBOSE, "Found plug: %s\n",info->getName().c_str()); 
    96  
     96     
    9797    // plug name 
    9898    result &= plug.setName(info->getName()); 
    99  
     99     
    100100    // plug type 
    101101    switch (info->m_plug_type) { 
     
    119119            break; 
    120120    } 
    121  
     121     
    122122    // number of channels 
    123123    result &= plug.setNrOfChannels(info->m_nb_channels); 
    124  
     124     
    125125    int idx=1; 
    126126    for ( AVCMusicClusterInfoBlockVectorIterator it = info->m_Clusters.begin(); 
    127           it != info->m_Clusters.end(); 
    128           ++it ) 
     127      it != info->m_Clusters.end(); 
     128      ++it ) 
    129129    { 
    130130        struct Plug::ClusterInfo cinfo; 
    131  
     131         
    132132        AVCMusicClusterInfoBlock *c=(*it); 
    133  
     133         
    134134        cinfo.m_index=idx; //FIXME: is this correct? 
    135135        cinfo.m_portType=c->m_port_type; 
     
    141141            cinfo.m_index, cinfo.m_portType, cinfo.m_nrOfChannels, cinfo.m_streamFormat, cinfo.m_name.c_str()); 
    142142 
    143         for ( AVCMusicClusterInfoBlock::SignalInfoVectorIterator sig_it 
    144                   = c->m_SignalInfos.begin(); 
    145               sig_it != c->m_SignalInfos.end(); 
    146               ++sig_it ) 
     143        for ( AVCMusicClusterInfoBlock::SignalInfoVectorIterator sig_it  
     144              = c->m_SignalInfos.begin(); 
     145            sig_it != c->m_SignalInfos.end(); 
     146            ++sig_it ) 
    147147        { 
    148148            struct AVCMusicClusterInfoBlock::sSignalInfo s=(*sig_it); 
    149149            struct Plug::ChannelInfo sinfo; 
    150  
     150             
    151151            sinfo.m_streamPosition=s.stream_position; 
    152152            sinfo.m_location=s.stream_location; 
    153  
     153             
    154154            AVCMusicPlugInfoBlock *mplug=m_status_descriptor->getMusicPlugInfoBlock(s.music_plug_id); 
    155  
     155             
    156156            if (mplug==NULL) { 
    157157                debugWarning("No music plug found for this signal\n"); 
     
    160160                sinfo.m_name=mplug->getName(); 
    161161            } 
    162  
     162             
    163163            if (plug.getDirection() == Plug::eAPD_Input) { 
    164                 // it's an input plug to the subunit 
     164                // it's an input plug to the subunit  
    165165                // so we have to check the source field of the music plug 
    166166                if(s.stream_position != mplug->m_source_stream_position) { 
     
    177177                } 
    178178            } else if (plug.getDirection() == Plug::eAPD_Output) { 
    179                 // it's an output plug from the subunit 
     179                // it's an output plug from the subunit  
    180180                // so we have to check the destination field of the music plug 
    181181                if(s.stream_position != mplug->m_dest_stream_position) { 
     
    194194                debugWarning("Invalid plug direction.\n"); 
    195195            } 
    196  
     196             
    197197            debugOutput(DEBUG_LEVEL_VERBOSE, "Adding signal pos=%2d loc=%2d name=%s\n", 
    198198                sinfo.m_streamPosition, sinfo.m_location, mplug->getName().c_str()); 
    199  
     199             
    200200            cinfo.m_channelInfos.push_back(sinfo); 
    201201        } 
     
    204204        plug.getClusterInfos().push_back(cinfo); 
    205205    } 
    206  
    207  
     206     
     207     
    208208    return result; 
    209209 
     
    239239bool 
    240240SubunitMusic::serializeChild( Glib::ustring basePath, 
    241                               Util::IOSerialize& ser ) const 
     241                                             Util::IOSerialize& ser ) const 
    242242{ 
    243243    return true; 
     
    246246bool 
    247247SubunitMusic::deserializeChild( Glib::ustring basePath, 
    248                                 Util::IODeserialize& deser, 
    249                                 Unit& unit ) 
     248                                               Util::IODeserialize& deser, 
     249                                               Unit& unit ) 
    250250{ 
    251251    return true; 
  • trunk/libffado/src/libieee1394/configrom.cpp

    r711 r734  
    6464    , m_1394Service( &ieee1394service ) 
    6565    , m_nodeId( nodeId ) 
    66     , m_avcDevice( false ) // FIXME: this does not seem veryu 
     66    , m_avcDevice( false ) 
    6767    , m_guid( 0 ) 
    6868    , m_vendorName( "" ) 
     
    9191    , m_1394Service( 0 ) 
    9292    , m_nodeId( -1 ) 
    93     , m_avcDevice( false ) // FIXME: this does not seem veryu 
     93    , m_avcDevice( false ) 
    9494    , m_guid( 0 ) 
    9595    , m_vendorName( "" ) 
     
    292292                if ( m_unit_specifier_id == 0x0000a02d ) // XXX 
    293293                { 
    294                     m_avcDevice = true; // FIXME: disable this check for the moment 
    295                     if ( kv->value.immediate == 0x14001 ) { 
     294                    if ( kv->value.immediate == 0x10001 ) { 
    296295                        m_avcDevice = true; 
    297296                    } 
  • trunk/libffado/src/libstreaming/StreamProcessorManager.cpp

    r512 r734  
    2323 
    2424#include "StreamProcessorManager.h" 
    25 #include "StreamProcessor.h" 
    26 #include "Port.h" 
     25#include "generic/StreamProcessor.h" 
     26#include "generic/Port.h" 
     27#include "util/cycletimer.h" 
     28 
    2729#include <errno.h> 
    2830#include <assert.h> 
    29  
    30 #include "libstreaming/cycletimer.h" 
    31  
    32 #define CYCLES_TO_SLEEP_AFTER_RUN_SIGNAL 5 
     31#include <math.h> 
    3332 
    3433#define RUNNING_TIMEOUT_MSEC 4000 
     
    3635#define ENABLE_TIMEOUT_MSEC 4000 
    3736 
    38 //#define ENABLE_DELAY_CYCLES 100 
    39 #define ENABLE_DELAY_CYCLES 1000 
     37// allows to add some processing margin. This shifts the time 
     38// at which the buffer is transfer()'ed, making things somewhat 
     39// more robust. It should be noted though that shifting the transfer 
     40// time to a later time instant also causes the xmit buffer fill to be 
     41// lower on average. 
     42#define FFADO_SIGNAL_DELAY_TICKS 3072*4 
    4043 
    4144namespace Streaming { 
    4245 
    43 IMPL_DEBUG_MODULE( StreamProcessorManager, StreamProcessorManager, DEBUG_LEVEL_NORMAL ); 
    44  
    45 StreamProcessorManager::StreamProcessorManager(unsigned int period, unsigned int nb_buffers) 
     46IMPL_DEBUG_MODULE( StreamProcessorManager, StreamProcessorManager, DEBUG_LEVEL_VERBOSE ); 
     47 
     48StreamProcessorManager::StreamProcessorManager(unsigned int period, unsigned int framerate, unsigned int nb_buffers) 
    4649    : m_is_slave( false ) 
    4750    , m_SyncSource(NULL) 
    4851    , m_nb_buffers(nb_buffers) 
    4952    , m_period(period) 
     53    , m_nominal_framerate ( framerate ) 
    5054    , m_xruns(0) 
    5155    , m_isoManager(0) 
     
    5761StreamProcessorManager::~StreamProcessorManager() { 
    5862    if (m_isoManager) delete m_isoManager; 
    59  
    6063} 
    6164 
     
    7780    assert(m_isoManager); 
    7881 
    79     if (processor->getType()==StreamProcessor::E_Receive) { 
     82    if (processor->getType() == StreamProcessor::ePT_Receive) { 
    8083        processor->setVerboseLevel(getDebugLevel()); // inherit debug level 
    8184 
    8285        m_ReceiveProcessors.push_back(processor); 
    83  
    8486        processor->setManager(this); 
    85  
    8687        return true; 
    8788    } 
    8889 
    89     if (processor->getType()==StreamProcessor::E_Transmit) { 
     90    if (processor->getType() == StreamProcessor::ePT_Transmit) { 
    9091        processor->setVerboseLevel(getDebugLevel()); // inherit debug level 
    9192 
    9293        m_TransmitProcessors.push_back(processor); 
    93  
    9494        processor->setManager(this); 
    95  
    9695        return true; 
    9796    } 
    9897 
    9998    debugFatal("Unsupported processor type!\n"); 
    100  
    10199    return false; 
    102100} 
     
    107105    assert(processor); 
    108106 
    109     if (processor->getType()==StreamProcessor::E_Receive) { 
     107    if (processor->getType()==StreamProcessor::ePT_Receive) { 
    110108 
    111109        for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    112             it != m_ReceiveProcessors.end(); 
    113             ++it ) { 
    114  
     110              it != m_ReceiveProcessors.end(); 
     111              ++it ) 
     112        { 
    115113            if ( *it == processor ) { 
    116                     m_ReceiveProcessors.erase(it); 
    117  
    118                     processor->clearManager(); 
    119  
    120                     if(!m_isoManager->unregisterStream(processor)) { 
    121                         debugOutput(DEBUG_LEVEL_VERBOSE,"Could not unregister receive stream processor from the Iso manager\n"); 
    122  
    123                         return false; 
    124  
    125                     } 
    126  
    127                     return true; 
     114                m_ReceiveProcessors.erase(it); 
     115                processor->clearManager(); 
     116                if(!m_isoManager->unregisterStream(processor)) { 
     117                    debugOutput(DEBUG_LEVEL_VERBOSE,"Could not unregister receive stream processor from the Iso manager\n"); 
     118                    return false; 
    128119                } 
    129         } 
    130     } 
    131  
    132     if (processor->getType()==StreamProcessor::E_Transmit) { 
     120                return true; 
     121            } 
     122        } 
     123    } 
     124 
     125    if (processor->getType()==StreamProcessor::ePT_Transmit) { 
    133126        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    134             it != m_TransmitProcessors.end(); 
    135             ++it ) { 
    136  
     127              it != m_TransmitProcessors.end(); 
     128              ++it ) 
     129        { 
    137130            if ( *it == processor ) { 
    138                     m_TransmitProcessors.erase(it); 
    139  
    140                     processor->clearManager(); 
    141  
    142                     if(!m_isoManager->unregisterStream(processor)) { 
    143                         debugOutput(DEBUG_LEVEL_VERBOSE,"Could not unregister transmit stream processor from the Iso manager\n"); 
    144  
    145                         return false; 
    146  
    147                     } 
    148  
    149                     return true; 
     131                m_TransmitProcessors.erase(it); 
     132                processor->clearManager(); 
     133                if(!m_isoManager->unregisterStream(processor)) { 
     134                    debugOutput(DEBUG_LEVEL_VERBOSE,"Could not unregister transmit stream processor from the Iso manager\n"); 
     135                    return false; 
    150136                } 
     137                return true; 
     138            } 
    151139        } 
    152140    } 
    153141 
    154142    debugFatal("Processor (%p) not found!\n",processor); 
    155  
    156143    return false; //not found 
    157  
    158144} 
    159145 
    160146bool StreamProcessorManager::setSyncSource(StreamProcessor *s) { 
    161147    debugOutput( DEBUG_LEVEL_VERBOSE, "Setting sync source to (%p)\n", s); 
    162  
    163148    m_SyncSource=s; 
    164149    return true; 
    165 } 
    166  
    167 StreamProcessor *StreamProcessorManager::getSyncSource() { 
    168     return m_SyncSource; 
    169150} 
    170151 
     
    172153{ 
    173154    debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 
    174  
    175     m_isoManager=new IsoHandlerManager(m_thread_realtime, m_thread_priority); 
    176  
     155    m_isoManager = new IsoHandlerManager(m_thread_realtime, m_thread_priority + 1); 
    177156    if(!m_isoManager) { 
    178157        debugFatal("Could not create IsoHandlerManager\n"); 
    179158        return false; 
    180159    } 
    181  
    182     // propagate the debug level 
    183160    m_isoManager->setVerboseLevel(getDebugLevel()); 
     161     
     162    // try to queue up 75% of the frames in the transmit buffer 
     163    unsigned int nb_frames = (getNbBuffers() - 1) * getPeriodSize() * 1000 / 2000; 
     164    m_isoManager->setTransmitBufferNbFrames(nb_frames); 
    184165 
    185166    if(!m_isoManager->init()) { 
     
    189170 
    190171    m_xrun_happened=false; 
    191  
    192172    return true; 
    193173} 
     
    207187    } 
    208188 
     189    // FIXME: put into separate method 
     190    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     191          it != m_ReceiveProcessors.end(); 
     192          ++it ) 
     193    { 
     194        if(m_SyncSource == NULL) { 
     195            debugWarning(" => Sync Source is %p.\n", *it); 
     196            m_SyncSource = *it; 
     197        } 
     198    } 
     199    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     200          it != m_TransmitProcessors.end(); 
     201          ++it ) 
     202    { 
     203        if(m_SyncSource == NULL) { 
     204            debugWarning(" => Sync Source is %p.\n", *it); 
     205            m_SyncSource = *it; 
     206        } 
     207    } 
     208 
     209    // now do the actual preparation of the SP's 
     210    debugOutput( DEBUG_LEVEL_VERBOSE, "Prepare Receive processors...\n"); 
    209211    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    210212        it != m_ReceiveProcessors.end(); 
    211213        ++it ) { 
    212             if(m_SyncSource == NULL) { 
    213                 debugWarning(" => Sync Source is %p.\n", *it); 
    214                 m_SyncSource = *it; 
    215             } 
    216     } 
    217  
    218     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    219         it != m_TransmitProcessors.end(); 
    220         ++it ) { 
    221             if(m_SyncSource == NULL) { 
    222                 debugWarning(" => Sync Source is %p.\n", *it); 
    223                 m_SyncSource = *it; 
    224             } 
    225     } 
    226  
    227     // now do the actual preparation 
    228     debugOutput( DEBUG_LEVEL_VERBOSE, "Prepare Receive processors...\n"); 
    229     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    230         it != m_ReceiveProcessors.end(); 
    231         ++it ) { 
    232  
    233         if(!(*it)->setSyncSource(m_SyncSource)) { 
    234             debugFatal(  " could not set sync source (%p)...\n",(*it)); 
    235             return false; 
    236         } 
    237214 
    238215        if(!(*it)->setOption("slaveMode", m_is_slave)) { 
     
    245222        } 
    246223    } 
    247  
    248224    debugOutput( DEBUG_LEVEL_VERBOSE, "Prepare Transmit processors...\n"); 
    249225    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    250226        it != m_TransmitProcessors.end(); 
    251227        ++it ) { 
    252         if(!(*it)->setSyncSource(m_SyncSource)) { 
    253             debugFatal(  " could not set sync source (%p)...\n",(*it)); 
    254             return false; 
    255         } 
    256228        if(!(*it)->setOption("slaveMode", m_is_slave)) { 
    257229            debugOutput(DEBUG_LEVEL_VERBOSE, " note: could not set slaveMode option for (%p)...\n",(*it)); 
     
    269241        return false; 
    270242    } 
    271  
    272243    return true; 
    273244} 
    274245 
    275 bool StreamProcessorManager::syncStartAll() { 
    276  
    277     debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for StreamProcessor streams to start running...\n"); 
    278     // we have to wait until all streamprocessors indicate that they are running 
    279     // i.e. that there is actually some data stream flowing 
    280     int wait_cycles=RUNNING_TIMEOUT_MSEC; // two seconds 
    281     bool notRunning=true; 
    282     while (notRunning && wait_cycles) { 
    283         wait_cycles--; 
    284         notRunning=false; 
    285  
     246bool StreamProcessorManager::startDryRunning() { 
     247    debugOutput( DEBUG_LEVEL_VERBOSE, "Putting StreamProcessor streams into dry-running state...\n"); 
     248    debugOutput( DEBUG_LEVEL_VERBOSE, " Schedule start dry-running...\n"); 
     249    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     250            it != m_ReceiveProcessors.end(); 
     251            ++it ) { 
     252        if (!(*it)->isDryRunning()) { 
     253            if(!(*it)->scheduleStartDryRunning(-1)) { 
     254                debugError("Could not put SP %p into the dry-running state\n", *it); 
     255                return false; 
     256            } 
     257        } else { 
     258            debugOutput( DEBUG_LEVEL_VERBOSE, " SP %p already dry-running...\n", *it); 
     259        } 
     260    } 
     261    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     262            it != m_TransmitProcessors.end(); 
     263            ++it ) { 
     264        if (!(*it)->isDryRunning()) { 
     265            if(!(*it)->scheduleStartDryRunning(-1)) { 
     266                debugError("Could not put SP %p into the dry-running state\n", *it); 
     267                return false; 
     268            } 
     269        } else { 
     270            debugOutput( DEBUG_LEVEL_VERBOSE, " SP %p already dry-running...\n", *it); 
     271        } 
     272    } 
     273    debugOutput( DEBUG_LEVEL_VERBOSE, " Waiting for all SP's to be dry-running...\n"); 
     274    // wait for the syncsource to start running. 
     275    // that will block the waitForPeriod call until everyone has started (theoretically) 
     276    #define CYCLES_FOR_DRYRUN 40000 
     277    int cnt = CYCLES_FOR_DRYRUN; // by then it should have started 
     278    bool all_dry_running = false; 
     279    while (!all_dry_running && cnt) { 
     280        all_dry_running = true; 
    286281        for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    287282                it != m_ReceiveProcessors.end(); 
    288283                ++it ) { 
    289             if(!(*it)->isRunning()) notRunning=true; 
    290         } 
    291  
     284            all_dry_running &= (*it)->isDryRunning(); 
     285        } 
    292286        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    293287                it != m_TransmitProcessors.end(); 
    294288                ++it ) { 
    295             if(!(*it)->isRunning()) notRunning=true; 
    296         } 
    297  
    298         // EXPERIMENT: 
    299         // the only stream that should be running is the sync 
    300         // source stream, as this is the one that defines 
    301         // when to signal buffers. Maybe we get an xrun at startup, 
    302         // but that should be handled. 
    303  
    304         // the problem is that otherwise a setup with a device 
    305         // that waits for decent input before sending output 
    306         // will not start up (e.g. the bounce device), because 
    307         // all streams are required to be running. 
    308  
    309         // other streams still have at least ENABLE_DELAY_CYCLES cycles 
    310         // to start up 
    311 //         if(!m_SyncSource->isRunning()) notRunning=true; 
    312  
    313         usleep(1000); 
    314         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Running check: %d\n",notRunning); 
    315     } 
    316  
    317     if(!wait_cycles) { // timout has occurred 
    318         debugFatal("One or more streams are not starting up (timeout):\n"); 
    319  
     289            all_dry_running &= (*it)->isDryRunning(); 
     290        } 
     291 
     292        usleep(125); 
     293        cnt--; 
     294    } 
     295    if(cnt==0) { 
     296        debugOutput(DEBUG_LEVEL_VERBOSE, " Timeout waiting for the SP's to start dry-running\n"); 
    320297        for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    321298                it != m_ReceiveProcessors.end(); 
    322299                ++it ) { 
    323             if(!(*it)->isRunning()) { 
    324                 debugFatal(" receive stream %p not running\n",*it); 
    325             } else { 
    326                 debugFatal(" receive stream %p running\n",*it); 
    327             } 
    328         } 
    329  
     300            debugOutput( DEBUG_LEVEL_VERBOSE, " %s SP %p has state %s\n", 
     301                (*it)->getTypeString(), *it, (*it)->getStateString()); 
     302        } 
    330303        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    331304                it != m_TransmitProcessors.end(); 
    332305                ++it ) { 
    333             if(!(*it)->isRunning()) { 
    334                 debugFatal(" transmit stream %p not running\n",*it); 
    335             } else { 
    336                 debugFatal(" transmit stream %p running\n",*it); 
    337             } 
    338         } 
    339         return false; 
    340     } 
    341  
    342     // we want to make sure that everything is running well, 
    343     // so wait for a while 
    344     usleep(USECS_PER_CYCLE * CYCLES_TO_SLEEP_AFTER_RUN_SIGNAL); 
    345  
     306            debugOutput( DEBUG_LEVEL_VERBOSE, " %s SP %p has state %s\n", 
     307                (*it)->getTypeString(), *it, (*it)->getStateString()); 
     308        } 
     309        return false; 
     310    } 
     311    debugOutput( DEBUG_LEVEL_VERBOSE, " StreamProcessor streams dry-running...\n"); 
     312    return true; 
     313
     314 
     315bool StreamProcessorManager::syncStartAll() { 
     316    // figure out when to get the SP's running. 
     317    // the xmit SP's should also know the base timestamp 
     318    // streams should be aligned here 
     319 
     320    // now find out how long we have to delay the wait operation such that 
     321    // the received frames will all be presented to the SP 
     322    debugOutput( DEBUG_LEVEL_VERBOSE, "Finding minimal sync delay...\n"); 
     323    int max_of_min_delay = 0; 
     324    int min_delay = 0; 
     325    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     326            it != m_ReceiveProcessors.end(); 
     327            ++it ) { 
     328        min_delay = (*it)->getMaxFrameLatency(); 
     329        if(min_delay > max_of_min_delay) max_of_min_delay = min_delay; 
     330    } 
     331 
     332    // add some processing margin. This only shifts the time 
     333    // at which the buffer is transfer()'ed. This makes things somewhat 
     334    // more robust. It should be noted though that shifting the transfer 
     335    // time to a later time instant also causes the xmit buffer fill to be 
     336    // lower on average. 
     337    max_of_min_delay += FFADO_SIGNAL_DELAY_TICKS; 
     338    debugOutput( DEBUG_LEVEL_VERBOSE, " sync delay = %d ticks (%03us %04uc %04ut)...\n",  
     339        max_of_min_delay, 
     340        (unsigned int)TICKS_TO_SECS(max_of_min_delay), 
     341        (unsigned int)TICKS_TO_CYCLES(max_of_min_delay), 
     342        (unsigned int)TICKS_TO_OFFSET(max_of_min_delay)); 
     343    m_SyncSource->setSyncDelay(max_of_min_delay); 
     344 
     345    //STEP X: when we implement such a function, we can wait for a signal from the devices that they 
     346    //        have aquired lock 
     347    //debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for device(s) to indicate clock sync lock...\n"); 
     348    //sleep(2); // FIXME: be smarter here 
     349 
     350    // make sure that we are dry-running long enough for the 
     351    // DLL to have a decent sync (FIXME: does the DLL get updated when dry-running)? 
     352    debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for sync...\n"); 
     353    int nb_sync_runs=20; 
     354    int64_t time_till_next_period; 
     355    while(nb_sync_runs--) { // or while not sync-ed? 
     356        // check if we were woken up too soon 
     357        time_till_next_period = m_SyncSource->getTimeUntilNextPeriodSignalUsecs(); 
     358        debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "waiting for %d usecs...\n", time_till_next_period); 
     359        if(time_till_next_period > 0) { 
     360            // wait for the period 
     361            usleep(time_till_next_period); 
     362        } 
     363    } 
     364 
     365    debugOutput( DEBUG_LEVEL_VERBOSE, "Propagate sync info...\n"); 
     366    // FIXME: in the SPM it would be nice to have system time instead of 
     367    //        1394 time 
     368 
     369    // we now should have decent sync info on the sync source 
     370    // determine a point in time where the system should start 
     371    // figure out where we are now 
     372    uint64_t time_of_first_sample = m_SyncSource->getTimeAtPeriod(); 
     373    debugOutput( DEBUG_LEVEL_VERBOSE, " sync at TS=%011llu (%03us %04uc %04ut)...\n",  
     374        time_of_first_sample, 
     375        (unsigned int)TICKS_TO_SECS(time_of_first_sample), 
     376        (unsigned int)TICKS_TO_CYCLES(time_of_first_sample), 
     377        (unsigned int)TICKS_TO_OFFSET(time_of_first_sample)); 
     378 
     379    #define CYCLES_FOR_STARTUP 2000 
     380    // start wet-running in CYCLES_FOR_STARTUP cycles 
     381    // this is the time window we have to setup all SP's such that they  
     382    // can start wet-running correctly. 
     383    time_of_first_sample = addTicks(time_of_first_sample, 
     384                                    CYCLES_FOR_STARTUP * TICKS_PER_CYCLE); 
     385 
     386    debugOutput( DEBUG_LEVEL_VERBOSE, "  => first sample at TS=%011llu (%03us %04uc %04ut)...\n",  
     387        time_of_first_sample, 
     388        (unsigned int)TICKS_TO_SECS(time_of_first_sample), 
     389        (unsigned int)TICKS_TO_CYCLES(time_of_first_sample), 
     390        (unsigned int)TICKS_TO_OFFSET(time_of_first_sample)); 
     391 
     392    // we should start wet-running the transmit SP's some cycles in advance 
     393    // such that we know it is wet-running when it should output its first sample 
     394    #define PRESTART_CYCLES_FOR_XMIT 20 
     395    uint64_t time_to_start_xmit = substractTicks(time_of_first_sample,  
     396                                                 PRESTART_CYCLES_FOR_XMIT * TICKS_PER_CYCLE); 
     397 
     398    #define PRESTART_CYCLES_FOR_RECV 0 
     399    uint64_t time_to_start_recv = substractTicks(time_of_first_sample, 
     400                                                 PRESTART_CYCLES_FOR_RECV * TICKS_PER_CYCLE); 
     401    debugOutput( DEBUG_LEVEL_VERBOSE, "  => xmit starts at  TS=%011llu (%03us %04uc %04ut)...\n",  
     402        time_to_start_xmit, 
     403        (unsigned int)TICKS_TO_SECS(time_to_start_xmit), 
     404        (unsigned int)TICKS_TO_CYCLES(time_to_start_xmit), 
     405        (unsigned int)TICKS_TO_OFFSET(time_to_start_xmit)); 
     406    debugOutput( DEBUG_LEVEL_VERBOSE, "  => recv starts at  TS=%011llu (%03us %04uc %04ut)...\n",  
     407        time_to_start_recv, 
     408        (unsigned int)TICKS_TO_SECS(time_to_start_recv), 
     409        (unsigned int)TICKS_TO_CYCLES(time_to_start_recv), 
     410        (unsigned int)TICKS_TO_OFFSET(time_to_start_recv)); 
     411 
     412    // at this point the buffer head timestamp of the transmit buffers can be set 
     413    // this is the presentation time of the first sample in the buffer 
     414    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     415          it != m_TransmitProcessors.end(); 
     416          ++it ) { 
     417        (*it)->setBufferHeadTimestamp(time_of_first_sample); 
     418    } 
     419 
     420    // STEP X: switch SP's over to the running state 
     421    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     422          it != m_ReceiveProcessors.end(); 
     423          ++it ) { 
     424        if(!(*it)->scheduleStartRunning(time_to_start_recv)) { 
     425            debugError("%p->scheduleStartRunning(%11llu) failed\n", *it, time_to_start_recv); 
     426            return false; 
     427        } 
     428    } 
     429    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     430          it != m_TransmitProcessors.end(); 
     431          ++it ) { 
     432        if(!(*it)->scheduleStartRunning(time_to_start_xmit)) { 
     433            debugError("%p->scheduleStartRunning(%11llu) failed\n", *it, time_to_start_xmit); 
     434            return false; 
     435        } 
     436    } 
     437    // wait for the syncsource to start running. 
     438    // that will block the waitForPeriod call until everyone has started (theoretically) 
     439    int cnt = CYCLES_FOR_STARTUP * 2; // by then it should have started 
     440    while (!m_SyncSource->isRunning() && cnt) { 
     441        usleep(125); 
     442        cnt--; 
     443    } 
     444    if(cnt==0) { 
     445        debugOutput(DEBUG_LEVEL_VERBOSE, " Timeout waiting for the SyncSource to get started\n"); 
     446        return false; 
     447    } 
     448 
     449    // now align the received streams 
     450    if(!alignReceivedStreams()) { 
     451        debugError("Could not align streams\n"); 
     452        return false; 
     453    } 
    346454    debugOutput( DEBUG_LEVEL_VERBOSE, " StreamProcessor streams running...\n"); 
    347  
    348     debugOutput( DEBUG_LEVEL_VERBOSE, "Finding minimal sync delay...\n"); 
    349  
    350     int max_of_min_delay=0; 
    351     int min_delay=0; 
    352     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    353             it != m_ReceiveProcessors.end(); 
    354             ++it ) { 
    355         min_delay=(*it)->getMinimalSyncDelay(); 
    356         if(min_delay>max_of_min_delay) max_of_min_delay=min_delay; 
    357     } 
    358  
    359     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    360             it != m_TransmitProcessors.end(); 
    361             ++it ) { 
    362         min_delay=(*it)->getMinimalSyncDelay(); 
    363         if(min_delay>max_of_min_delay) max_of_min_delay=min_delay; 
    364     } 
    365  
    366     debugOutput( DEBUG_LEVEL_VERBOSE, "  %d ticks\n", max_of_min_delay); 
    367     m_SyncSource->setSyncDelay(max_of_min_delay); 
    368  
    369  
    370     debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting StreamProcessors...\n"); 
    371     // now we reset the frame counters 
    372     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    373             it != m_ReceiveProcessors.end(); 
    374             ++it ) { 
    375         (*it)->reset(); 
    376     } 
    377  
    378     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    379             it != m_TransmitProcessors.end(); 
    380             ++it ) { 
    381         (*it)->reset(); 
    382     } 
    383  
    384     debugOutput( DEBUG_LEVEL_VERBOSE, "Enabling StreamProcessors...\n"); 
    385  
    386     uint64_t now=m_SyncSource->getTimeNow(); // fixme: should be in usecs, not ticks 
    387  
    388     // FIXME: this should not be in cycles, but in 'time' 
    389     unsigned int enable_at=TICKS_TO_CYCLES(now)+ENABLE_DELAY_CYCLES; 
    390     if (enable_at > 8000) enable_at -= 8000; 
    391  
    392     if (!enableStreamProcessors(enable_at)) { 
    393         debugFatal("Could not enable StreamProcessors...\n"); 
    394         return false; 
    395     } 
    396  
     455    return true; 
     456
     457 
     458bool 
     459StreamProcessorManager::alignReceivedStreams() 
     460
     461    #define NB_PERIODS_FOR_ALIGN_AVERAGE 20 
     462    #define NB_ALIGN_TRIES 20 
     463    debugOutput( DEBUG_LEVEL_VERBOSE, "Aligning received streams...\n"); 
     464    unsigned int nb_sync_runs; 
     465    unsigned int nb_rcv_sp = m_ReceiveProcessors.size(); 
     466    int64_t diff_between_streams[nb_rcv_sp]; 
     467    int64_t diff; 
     468 
     469    unsigned int i; 
     470 
     471    bool aligned = false; 
     472    int cnt = NB_ALIGN_TRIES; 
     473    while (!aligned && cnt--) { 
     474        nb_sync_runs = NB_PERIODS_FOR_ALIGN_AVERAGE; 
     475        while(nb_sync_runs) { 
     476            debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " check (%d)...\n", nb_sync_runs); 
     477            waitForPeriod(); 
     478 
     479            i = 0; 
     480            for ( i = 0; i < nb_rcv_sp; i++) { 
     481                StreamProcessor *s = m_ReceiveProcessors.at(i); 
     482                diff = diffTicks(m_SyncSource->getTimeAtPeriod(), s->getTimeAtPeriod()); 
     483                debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "  offset between SyncSP %p and SP %p is %lld ticks...\n",  
     484                    m_SyncSource, s, diff); 
     485                if ( nb_sync_runs == NB_PERIODS_FOR_ALIGN_AVERAGE ) { 
     486                    diff_between_streams[i] = diff; 
     487                } else { 
     488                    diff_between_streams[i] += diff; 
     489                } 
     490            } 
     491            if(!transferSilence()) { 
     492                debugError("Could not transfer silence\n"); 
     493                return false; 
     494            } 
     495            nb_sync_runs--; 
     496        } 
     497        // calculate the average offsets 
     498        debugOutput( DEBUG_LEVEL_VERBOSE, " Average offsets:\n"); 
     499        int diff_between_streams_frames[nb_rcv_sp]; 
     500        aligned = true; 
     501        for ( i = 0; i < nb_rcv_sp; i++) { 
     502            StreamProcessor *s = m_ReceiveProcessors.at(i); 
     503 
     504            diff_between_streams[i] /= NB_PERIODS_FOR_ALIGN_AVERAGE; 
     505            diff_between_streams_frames[i] = roundf(diff_between_streams[i] / s->getTicksPerFrame()); 
     506            debugOutput( DEBUG_LEVEL_VERBOSE, "   avg offset between SyncSP %p and SP %p is %lld ticks, %d frames...\n",  
     507                m_SyncSource, s, diff_between_streams[i], diff_between_streams_frames[i]); 
     508 
     509            aligned &= (diff_between_streams_frames[i] == 0); 
     510 
     511            // reposition the stream 
     512            if(!s->shiftStream(diff_between_streams_frames[i])) { 
     513                debugError("Could not shift SP %p %d frames\n", s, diff_between_streams_frames[i]); 
     514                return false; 
     515            } 
     516        } 
     517        if (!aligned) { 
     518            debugOutput(DEBUG_LEVEL_VERBOSE, "Streams not aligned, doing new round...\n"); 
     519        } 
     520    } 
     521    if (cnt == 0) { 
     522        debugError("Align failed\n"); 
     523        return false; 
     524    } 
    397525    return true; 
    398526} 
     
    405533    debugOutput( DEBUG_LEVEL_VERBOSE, " Receive processors...\n"); 
    406534    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    407         it != m_ReceiveProcessors.end(); 
    408         ++it ) { 
    409             if (!(*it)->prepareForStart()) { 
    410                 debugOutput(DEBUG_LEVEL_VERBOSE,"Receive stream processor (%p) failed to prepare for start\n", *it); 
    411                 return false; 
    412             } 
    413             if (!m_isoManager->registerStream(*it)) { 
    414                 debugOutput(DEBUG_LEVEL_VERBOSE,"Could not register receive stream processor (%p) with the Iso manager\n",*it); 
    415                 return false; 
    416             } 
    417         } 
    418  
     535          it != m_ReceiveProcessors.end(); 
     536          ++it ) 
     537    { 
     538        if (!m_isoManager->registerStream(*it)) { 
     539            debugOutput(DEBUG_LEVEL_VERBOSE,"Could not register receive stream processor (%p) with the Iso manager\n",*it); 
     540            return false; 
     541        } 
     542    } 
    419543    debugOutput( DEBUG_LEVEL_VERBOSE, " Transmit processors...\n"); 
    420544    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    421         it != m_TransmitProcessors.end(); 
    422         ++it ) { 
    423             if (!(*it)->prepareForStart()) { 
    424                 debugOutput(DEBUG_LEVEL_VERBOSE,"Transmit stream processor (%p) failed to prepare for start\n", *it); 
    425                 return false; 
    426             } 
    427             if (!m_isoManager->registerStream(*it)) { 
    428                 debugOutput(DEBUG_LEVEL_VERBOSE,"Could not register transmit stream processor (%p) with the Iso manager\n",*it); 
    429                 return false; 
    430             } 
    431         } 
     545          it != m_TransmitProcessors.end(); 
     546          ++it ) 
     547    { 
     548        if (!m_isoManager->registerStream(*it)) { 
     549            debugOutput(DEBUG_LEVEL_VERBOSE,"Could not register transmit stream processor (%p) with the Iso manager\n",*it); 
     550            return false; 
     551        } 
     552    } 
    432553 
    433554    debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing IsoHandlerManager...\n"); 
     
    437558    } 
    438559 
    439     debugOutput( DEBUG_LEVEL_VERBOSE, "Disabling StreamProcessors...\n"); 
    440         if (!disableStreamProcessors()) { 
    441         debugFatal("Could not disable StreamProcessors...\n"); 
    442         return false; 
    443     } 
    444  
    445560    debugOutput( DEBUG_LEVEL_VERBOSE, "Starting IsoHandlers...\n"); 
    446561    if (!m_isoManager->startHandlers(-1)) { 
     
    449564    } 
    450565 
     566    // put all SP's into dry-running state 
     567    if (!startDryRunning()) { 
     568        debugFatal("Could not put SP's in dry-running state\n"); 
     569        return false; 
     570    } 
     571 
    451572    // start all SP's synchonized 
    452573    if (!syncStartAll()) { 
     
    461582 
    462583    return true; 
    463  
    464584} 
    465585 
     
    468588    assert(m_isoManager); 
    469589 
    470     debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for all StreamProcessors to prepare to stop...\n"); 
    471     // Most stream processors can just stop without special treatment.  However, some 
    472     // (like the MOTU) need to do a few things before it's safe to turn off the iso 
    473     // handling. 
    474     int wait_cycles=PREPARE_TIMEOUT_MSEC; // two seconds ought to be sufficient 
    475     bool allReady = false; 
    476     while (!allReady && wait_cycles) { 
    477         wait_cycles--; 
    478         allReady = true; 
    479  
     590    debugOutput( DEBUG_LEVEL_VERBOSE, " scheduling stop for all SP's...\n"); 
     591 
     592    // switch SP's over to the dry-running state 
     593    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     594          it != m_ReceiveProcessors.end(); 
     595          ++it ) { 
     596        if(!(*it)->scheduleStopRunning(-1)) { 
     597            debugError("%p->scheduleStopRunning(-1) failed\n", *it); 
     598            return false; 
     599        } 
     600    } 
     601    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     602          it != m_TransmitProcessors.end(); 
     603          ++it ) { 
     604        if(!(*it)->scheduleStopRunning(-1)) { 
     605            debugError("%p->scheduleStopRunning(-1) failed\n", *it); 
     606            return false; 
     607        } 
     608    } 
     609    // wait for the SP's to get into the dry-running state 
     610    int cnt = 200; 
     611    bool ready = false; 
     612    while (!ready && cnt) { 
     613        ready = true; 
    480614        for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    481615            it != m_ReceiveProcessors.end(); 
    482616            ++it ) { 
    483             if(!(*it)->prepareForStop()) allReady = false; 
    484         } 
    485  
     617            ready &= ((*it)->isDryRunning() || (*it)->isStopped()); 
     618        } 
    486619        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    487620            it != m_TransmitProcessors.end(); 
    488621            ++it ) { 
    489             if(!(*it)->prepareForStop()) allReady = false; 
    490         } 
    491         usleep(1000); 
    492     } 
    493  
     622            ready &= ((*it)->isDryRunning() || (*it)->isStopped()); 
     623        } 
     624        usleep(125); 
     625        cnt--; 
     626    } 
     627    if(cnt==0) { 
     628        debugOutput(DEBUG_LEVEL_VERBOSE, " Timeout waiting for the SP's to start dry-running\n"); 
     629        return false; 
     630    } 
     631 
     632    // switch SP's over to the stopped state 
     633    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     634          it != m_ReceiveProcessors.end(); 
     635          ++it ) { 
     636        if(!(*it)->scheduleStopDryRunning(-1)) { 
     637            debugError("%p->scheduleStopDryRunning(-1) failed\n", *it); 
     638            return false; 
     639        } 
     640    } 
     641    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     642          it != m_TransmitProcessors.end(); 
     643          ++it ) { 
     644        if(!(*it)->scheduleStopDryRunning(-1)) { 
     645            debugError("%p->scheduleStopDryRunning(-1) failed\n", *it); 
     646            return false; 
     647        } 
     648    } 
     649    // wait for the SP's to get into the running state 
     650    cnt = 200; 
     651    ready = false; 
     652    while (!ready && cnt) { 
     653        ready = true; 
     654        for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     655            it != m_ReceiveProcessors.end(); 
     656            ++it ) { 
     657            ready &= (*it)->isStopped(); 
     658        } 
     659        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     660            it != m_TransmitProcessors.end(); 
     661            ++it ) { 
     662            ready &= (*it)->isStopped(); 
     663        } 
     664        usleep(125); 
     665        cnt--; 
     666    } 
     667    if(cnt==0) { 
     668        debugOutput(DEBUG_LEVEL_VERBOSE, " Timeout waiting for the SP's to stop\n"); 
     669        return false; 
     670    } 
    494671 
    495672    debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping handlers...\n"); 
     
    503680    debugOutput( DEBUG_LEVEL_VERBOSE, " Receive processors...\n"); 
    504681    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    505         it != m_ReceiveProcessors.end(); 
    506         ++it ) { 
    507             if (!m_isoManager->unregisterStream(*it)) { 
    508                 debugOutput(DEBUG_LEVEL_VERBOSE,"Could not unregister receive stream processor (%p) from the Iso manager\n",*it); 
    509                 return false; 
    510             } 
    511  
    512         } 
    513  
     682          it != m_ReceiveProcessors.end(); 
     683          ++it ) { 
     684        if (!m_isoManager->unregisterStream(*it)) { 
     685            debugOutput(DEBUG_LEVEL_VERBOSE,"Could not unregister receive stream processor (%p) from the Iso manager\n",*it); 
     686            return false; 
     687        } 
     688    } 
    514689    debugOutput( DEBUG_LEVEL_VERBOSE, " Transmit processors...\n"); 
    515690    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    516         it != m_TransmitProcessors.end(); 
    517         ++it ) { 
    518             if (!m_isoManager->unregisterStream(*it)) { 
    519                 debugOutput(DEBUG_LEVEL_VERBOSE,"Could not unregister transmit stream processor (%p) from the Iso manager\n",*it); 
    520                 return false; 
    521             } 
    522  
    523         } 
    524  
    525     return true; 
    526  
    527 
    528  
    529 /** 
    530  * Enables the registered StreamProcessors 
    531  * @return true if successful, false otherwise 
    532  */ 
    533 bool StreamProcessorManager::enableStreamProcessors(uint64_t time_to_enable_at) { 
    534     debugOutput( DEBUG_LEVEL_VERBOSE, "Enabling StreamProcessors at %llu...\n", time_to_enable_at); 
    535  
    536     debugOutput( DEBUG_LEVEL_VERBOSE, " Sync Source StreamProcessor (%p)...\n",m_SyncSource); 
    537     debugOutput( DEBUG_LEVEL_VERBOSE, "  Prepare...\n"); 
    538     if (!m_SyncSource->prepareForEnable(time_to_enable_at)) { 
    539             debugFatal("Could not prepare Sync Source StreamProcessor for enable()...\n"); 
    540         return false; 
    541     } 
    542  
    543     debugOutput( DEBUG_LEVEL_VERBOSE, "  Enable...\n"); 
    544     m_SyncSource->enable(time_to_enable_at); 
    545  
    546     debugOutput( DEBUG_LEVEL_VERBOSE, " Other StreamProcessors...\n"); 
    547  
    548     // we prepare the streamprocessors for enable 
    549     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    550             it != m_ReceiveProcessors.end(); 
    551             ++it ) { 
    552         if(*it != m_SyncSource) { 
    553             debugOutput( DEBUG_LEVEL_VERBOSE, " Prepare Receive SP (%p)...\n",*it); 
    554             (*it)->prepareForEnable(time_to_enable_at); 
    555         } 
    556     } 
    557  
    558     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    559             it != m_TransmitProcessors.end(); 
    560             ++it ) { 
    561         if(*it != m_SyncSource) { 
    562             debugOutput( DEBUG_LEVEL_VERBOSE, " Prepare Transmit SP (%p)...\n",*it); 
    563             (*it)->prepareForEnable(time_to_enable_at); 
    564         } 
    565     } 
    566  
    567     // then we enable the streamprocessors 
    568     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    569             it != m_ReceiveProcessors.end(); 
    570             ++it ) { 
    571         if(*it != m_SyncSource) { 
    572             debugOutput( DEBUG_LEVEL_VERBOSE, " Enable Receive SP (%p)...\n",*it); 
    573             (*it)->enable(time_to_enable_at); 
    574         } 
    575     } 
    576  
    577     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    578             it != m_TransmitProcessors.end(); 
    579             ++it ) { 
    580         if(*it != m_SyncSource) { 
    581             debugOutput( DEBUG_LEVEL_VERBOSE, " Enable Transmit SP (%p)...\n",*it); 
    582             (*it)->enable(time_to_enable_at); 
    583         } 
    584     } 
    585  
    586     // now we wait for the SP's to get enabled 
    587     debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for all StreamProcessors to be enabled...\n"); 
    588     // we have to wait until all streamprocessors indicate that they are running 
    589     // i.e. that there is actually some data stream flowing 
    590     int wait_cycles=ENABLE_TIMEOUT_MSEC; // two seconds 
    591     bool notEnabled=true; 
    592     while (notEnabled && wait_cycles) { 
    593         wait_cycles--; 
    594         notEnabled=false; 
    595  
    596         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    597                 it != m_ReceiveProcessors.end(); 
    598                 ++it ) { 
    599             if(!(*it)->isEnabled()) notEnabled=true; 
    600         } 
    601  
    602         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    603                 it != m_TransmitProcessors.end(); 
    604                 ++it ) { 
    605             if(!(*it)->isEnabled()) notEnabled=true; 
    606         } 
    607         usleep(1000); // one cycle 
    608     } 
    609  
    610     if(!wait_cycles) { // timout has occurred 
    611         debugFatal("One or more streams couldn't be enabled (timeout):\n"); 
    612  
    613         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    614                 it != m_ReceiveProcessors.end(); 
    615                 ++it ) { 
    616             if(!(*it)->isEnabled()) { 
    617                     debugFatal(" receive stream %p not enabled\n",*it); 
    618             } else { 
    619                     debugFatal(" receive stream %p enabled\n",*it); 
    620             } 
    621         } 
    622  
    623         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    624                 it != m_TransmitProcessors.end(); 
    625                 ++it ) { 
    626             if(!(*it)->isEnabled()) { 
    627                     debugFatal(" transmit stream %p not enabled\n",*it); 
    628             } else { 
    629                     debugFatal(" transmit stream %p enabled\n",*it); 
    630             } 
    631         } 
    632         return false; 
    633     } 
    634  
    635     debugOutput( DEBUG_LEVEL_VERBOSE, " => all StreamProcessors enabled...\n"); 
    636  
    637     return true; 
    638 
    639  
    640 /** 
    641  * Disables the registered StreamProcessors 
    642  * @return true if successful, false otherwise 
    643  */ 
    644 bool StreamProcessorManager::disableStreamProcessors() { 
    645     // we prepare the streamprocessors for disable 
    646     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    647             it != m_ReceiveProcessors.end(); 
    648             ++it ) { 
    649         (*it)->prepareForDisable(); 
    650     } 
    651  
    652     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    653             it != m_TransmitProcessors.end(); 
    654             ++it ) { 
    655         (*it)->prepareForDisable(); 
    656     } 
    657  
    658     // then we disable the streamprocessors 
    659     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    660             it != m_ReceiveProcessors.end(); 
    661             ++it ) { 
    662         (*it)->disable(); 
    663     } 
    664  
    665     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    666             it != m_TransmitProcessors.end(); 
    667             ++it ) { 
    668         (*it)->disable(); 
    669     } 
    670  
    671     // now we wait for the SP's to get disabled 
    672     debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for all StreamProcessors to be disabled...\n"); 
    673     // we have to wait until all streamprocessors indicate that they are running 
    674     // i.e. that there is actually some data stream flowing 
    675     int wait_cycles=ENABLE_TIMEOUT_MSEC; // two seconds 
    676     bool enabled=true; 
    677     while (enabled && wait_cycles) { 
    678         wait_cycles--; 
    679         enabled=false; 
    680  
    681         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    682                 it != m_ReceiveProcessors.end(); 
    683                 ++it ) { 
    684             if((*it)->isEnabled()) enabled=true; 
    685         } 
    686  
    687         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    688                 it != m_TransmitProcessors.end(); 
    689                 ++it ) { 
    690             if((*it)->isEnabled()) enabled=true; 
    691         } 
    692         usleep(1000); // one cycle 
    693     } 
    694  
    695     if(!wait_cycles) { // timout has occurred 
    696         debugFatal("One or more streams couldn't be disabled (timeout):\n"); 
    697  
    698         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    699                 it != m_ReceiveProcessors.end(); 
    700                 ++it ) { 
    701             if(!(*it)->isEnabled()) { 
    702                     debugFatal(" receive stream %p not enabled\n",*it); 
    703             } else { 
    704                     debugFatal(" receive stream %p enabled\n",*it); 
    705             } 
    706         } 
    707  
    708         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    709                 it != m_TransmitProcessors.end(); 
    710                 ++it ) { 
    711             if(!(*it)->isEnabled()) { 
    712                     debugFatal(" transmit stream %p not enabled\n",*it); 
    713             } else { 
    714                     debugFatal(" transmit stream %p enabled\n",*it); 
    715             } 
    716         } 
    717         return false; 
    718     } 
    719  
    720     debugOutput( DEBUG_LEVEL_VERBOSE, " => all StreamProcessors disabled...\n"); 
    721  
     691          it != m_TransmitProcessors.end(); 
     692          ++it ) { 
     693        if (!m_isoManager->unregisterStream(*it)) { 
     694            debugOutput(DEBUG_LEVEL_VERBOSE,"Could not unregister transmit stream processor (%p) from the Iso manager\n",*it); 
     695            return false; 
     696        } 
     697    } 
    722698    return true; 
    723699} 
     
    733709 
    734710    debugOutput( DEBUG_LEVEL_VERBOSE, "Handling Xrun ...\n"); 
     711 
     712    dumpInfo(); 
    735713 
    736714    /* 
     
    743721     * 3) Re-enable the SP's 
    744722     */ 
    745     debugOutput( DEBUG_LEVEL_VERBOSE, "Disabling StreamProcessors...\n"); 
    746         if (!disableStreamProcessors()) { 
    747         debugFatal("Could not disable StreamProcessors...\n"); 
     723 
     724    // put all SP's back into dry-running state 
     725    if (!startDryRunning()) { 
     726        debugFatal("Could not put SP's in dry-running state\n"); 
    748727        return false; 
    749728    } 
     
    771750bool StreamProcessorManager::waitForPeriod() { 
    772751    int time_till_next_period; 
    773     bool xrun_occurred=false; 
     752    bool xrun_occurred = false; 
    774753 
    775754    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "enter...\n"); 
     
    799778            xrun_occurred |= (*it)->xrunOccurred(); 
    800779        } 
     780        if(xrun_occurred) break; 
    801781 
    802782        // check if we were waked up too soon 
    803         time_till_next_period=m_SyncSource->getTimeUntilNextPeriodSignalUsecs(); 
    804     } 
    805  
    806     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "delayed for %d usecs...\n", time_till_next_period); 
    807  
    808     // this is to notify the client of the delay 
    809     // that we introduced 
    810     m_delayed_usecs=time_till_next_period; 
     783        time_till_next_period = m_SyncSource->getTimeUntilNextPeriodSignalUsecs(); 
     784    } 
    811785 
    812786    // we save the 'ideal' time of the transfer at this point, 
     
    816790    // NOTE: before waitForPeriod() is called again, both the transmit 
    817791    //       and the receive processors should have done their transfer. 
    818     m_time_of_transfer=m_SyncSource->getTimeAtPeriod(); 
     792    m_time_of_transfer = m_SyncSource->getTimeAtPeriod(); 
    819793    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "transfer at %llu ticks...\n", 
    820794        m_time_of_transfer); 
     795 
     796    // normally we can transfer frames at this time, but in some cases this is not true 
     797    // e.g. when there are not enough frames in the receive buffer. 
     798    // however this doesn't have to be a problem, since we can wait some more until we 
     799    // have enough frames. There is only a problem once the ISO xmit doesn't have packets 
     800    // to transmit, or if the receive buffer overflows. These conditions are signaled by 
     801    // the iso threads 
     802    // check if xruns occurred on the Iso side. 
     803    // also check if xruns will occur should we transfer() now 
     804    #ifdef DEBUG 
     805    int waited = 0; 
     806    #endif 
     807    bool ready_for_transfer = false; 
     808    xrun_occurred = false; 
     809    while (!ready_for_transfer && !xrun_occurred) { 
     810        ready_for_transfer = true; 
     811        for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     812            it != m_ReceiveProcessors.end(); 
     813            ++it ) { 
     814            ready_for_transfer &= ((*it)->canClientTransferFrames(m_period)); 
     815            xrun_occurred |= (*it)->xrunOccurred(); 
     816        } 
     817        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     818            it != m_TransmitProcessors.end(); 
     819            ++it ) { 
     820            ready_for_transfer &= ((*it)->canClientTransferFrames(m_period)); 
     821            xrun_occurred |= (*it)->xrunOccurred(); 
     822        } 
     823        if (!ready_for_transfer) { 
     824            usleep(125); // MAGIC: one cycle sleep... 
     825 
     826            // in order to avoid this in the future, we increase the sync delay of the sync source SP 
     827            int d = m_SyncSource->getSyncDelay() + TICKS_PER_CYCLE; 
     828            m_SyncSource->setSyncDelay(d); 
     829 
     830            #ifdef DEBUG 
     831            waited++; 
     832            #endif 
     833        } 
     834    } // we are either ready or an xrun occurred 
     835 
     836    #ifdef DEBUG 
     837    if(waited > 0) { 
     838        debugOutput(DEBUG_LEVEL_VERBOSE, "Waited %d x 125us due to SP not ready for transfer\n", waited); 
     839    } 
     840    #endif 
     841 
     842    // this is to notify the client of the delay that we introduced by waiting 
     843    m_delayed_usecs = - m_SyncSource->getTimeUntilNextPeriodSignalUsecs(); 
     844    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "delayed for %d usecs...\n", m_delayed_usecs); 
    821845 
    822846#ifdef DEBUG 
     
    833857    } 
    834858    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "XF at %011llu ticks, RBF=%d, XBF=%d, SUM=%d...\n", 
    835         m_time_of_transfer,rcv_bf,xmt_bf,rcv_bf+xmt_bf); 
    836  
    837 #endif 
    838  
    839     xrun_occurred=false; 
     859        m_time_of_transfer, rcv_bf, xmt_bf, rcv_bf+xmt_bf); 
    840860 
    841861    // check if xruns occurred on the Iso side. 
    842862    // also check if xruns will occur should we transfer() now 
    843  
    844863    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    845864          it != m_ReceiveProcessors.end(); 
    846865          ++it ) { 
    847         // a xrun has occurred on the Iso side 
    848         xrun_occurred |= (*it)->xrunOccurred(); 
    849  
    850         // if this is true, a xrun will occur 
    851         xrun_occurred |= !((*it)->canClientTransferFrames(m_period)); 
    852  
    853 #ifdef DEBUG 
     866 
    854867        if ((*it)->xrunOccurred()) { 
    855             debugWarning("Xrun on RECV SP %p due to ISO xrun\n",*it); 
     868            debugWarning("Xrun on RECV SP %p due to ISO side xrun\n",*it); 
    856869            (*it)->dumpInfo(); 
    857870        } 
    858871        if (!((*it)->canClientTransferFrames(m_period))) { 
    859             debugWarning("Xrun on RECV SP %p due to buffer xrun\n",*it); 
     872            debugWarning("Xrun on RECV SP %p due to buffer side xrun\n",*it); 
    860873            (*it)->dumpInfo(); 
    861874        } 
    862 #endif 
    863  
    864875    } 
    865876    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    866877          it != m_TransmitProcessors.end(); 
    867878          ++it ) { 
    868         // a xrun has occurred on the Iso side 
    869         xrun_occurred |= (*it)->xrunOccurred(); 
    870  
    871         // if this is true, a xrun will occur 
    872         xrun_occurred |= !((*it)->canClientTransferFrames(m_period)); 
    873  
    874 #ifdef DEBUG 
    875879        if ((*it)->xrunOccurred()) { 
    876             debugWarning("Xrun on XMIT SP %p due to ISO xrun\n",*it); 
     880            debugWarning("Xrun on XMIT SP %p due to ISO side xrun\n",*it); 
    877881        } 
    878882        if (!((*it)->canClientTransferFrames(m_period))) { 
    879             debugWarning("Xrun on XMIT SP %p due to buffer xrun\n",*it); 
    880         } 
     883            debugWarning("Xrun on XMIT SP %p due to buffer side xrun\n",*it); 
     884        } 
     885    } 
    881886#endif 
    882     } 
    883887 
    884888    m_nbperiods++; 
    885  
    886889    // now we can signal the client that we are (should be) ready 
    887890    return !xrun_occurred; 
     
    896899 */ 
    897900bool StreamProcessorManager::transfer() { 
    898  
    899     debugOutput( DEBUG_LEVEL_VERBOSE, "Transferring period...\n"); 
    900  
    901     if (!transfer(StreamProcessor::E_Receive)) return false; 
    902     if (!transfer(StreamProcessor::E_Transmit)) return false; 
    903  
    904     return true; 
     901    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n"); 
     902    bool retval=true; 
     903    retval &= transfer(StreamProcessor::ePT_Receive); 
     904    retval &= transfer(StreamProcessor::ePT_Transmit); 
     905    return retval; 
    905906} 
    906907 
     
    913914 * @return true if successful, false otherwise (indicates xrun). 
    914915 */ 
    915  
    916 bool StreamProcessorManager::transfer(enum StreamProcessor::EProcessorType t) { 
    917     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n"); 
    918  
     916bool StreamProcessorManager::transfer(enum StreamProcessor::eProcessorType t) { 
     917    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "transfer(%d) at TS=%011llu (%03us %04uc %04ut)...\n",  
     918        t, m_time_of_transfer, 
     919        (unsigned int)TICKS_TO_SECS(m_time_of_transfer), 
     920        (unsigned int)TICKS_TO_CYCLES(m_time_of_transfer), 
     921        (unsigned int)TICKS_TO_OFFSET(m_time_of_transfer)); 
     922 
     923    bool retval = true; 
    919924    // a static cast could make sure that there is no performance 
    920925    // penalty for the virtual functions (to be checked) 
    921     if (t==StreamProcessor::E_Receive) { 
    922          
    923         // determine the time at which we want reception to start 
    924         float rate=m_SyncSource->getTicksPerFrame(); 
    925         int64_t one_frame_in_ticks=(int64_t)(((float)m_period)*rate); 
    926          
    927         int64_t receive_timestamp = substractTicks(m_time_of_transfer,one_frame_in_ticks); 
    928          
    929         if(receive_timestamp<0) { 
    930             debugWarning("receive ts < 0.0 : %lld, m_time_of_transfer= %llu, one_frame_in_ticks=%lld\n", 
    931              receive_timestamp, m_time_of_transfer, one_frame_in_ticks); 
    932         } 
    933         if(receive_timestamp>(128L*TICKS_PER_SECOND)) { 
    934             debugWarning("receive ts > 128L*TICKS_PER_SECOND : %lld, m_time_of_transfer= %llu, one_frame_in_ticks=%lld\n", 
    935              receive_timestamp, m_time_of_transfer, one_frame_in_ticks); 
    936         } 
    937          
     926    if (t==StreamProcessor::ePT_Receive) { 
    938927        for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    939928                it != m_ReceiveProcessors.end(); 
    940929                ++it ) { 
    941  
    942             if(!(*it)->getFrames(m_period, receive_timestamp)) { 
    943                     debugOutput(DEBUG_LEVEL_VERBOSE,"could not getFrames(%u, %11llu) from stream processor (%p)\n", 
     930            if(!(*it)->getFrames(m_period, m_time_of_transfer)) { 
     931                    debugWarning("could not getFrames(%u, %11llu) from stream processor (%p)\n", 
    944932                            m_period, m_time_of_transfer,*it); 
    945                     return false; // buffer underrun 
    946             } 
    947  
     933                retval &= false; // buffer underrun 
     934            } 
    948935        } 
    949936    } else { 
     937        // FIXME: in the SPM it would be nice to have system time instead of 
     938        //        1394 time 
     939        float rate = m_SyncSource->getTicksPerFrame(); 
     940        int64_t one_ringbuffer_in_ticks=(int64_t)(((float)(m_nb_buffers * m_period)) * rate); 
     941 
     942        // the data we are putting into the buffer is intended to be transmitted 
     943        // one ringbuffer size after it has been received 
     944        int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks); 
     945 
    950946        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    951947                it != m_TransmitProcessors.end(); 
    952948                ++it ) { 
    953  
    954             if(!(*it)->putFrames(m_period, (int64_t)m_time_of_transfer)) { 
    955                 debugOutput(DEBUG_LEVEL_VERBOSE, "could not putFrames(%u,%llu) to stream processor (%p)\n", 
    956                         m_period, m_time_of_transfer, *it); 
    957                 return false; // buffer overrun 
    958             } 
    959  
    960         } 
    961     } 
    962  
    963     return true; 
     949            // FIXME: in the SPM it would be nice to have system time instead of 
     950            //        1394 time 
     951            if(!(*it)->putFrames(m_period, transmit_timestamp)) { 
     952                debugWarning("could not putFrames(%u,%llu) to stream processor (%p)\n", 
     953                        m_period, transmit_timestamp, *it); 
     954                retval &= false; // buffer underrun 
     955            } 
     956        } 
     957    } 
     958    return retval; 
     959
     960 
     961/** 
     962 * @brief Transfer one period of silence for both receive and transmit StreamProcessors 
     963 * 
     964 * Transfers one period of silence to the Iso side for transmit SP's 
     965 * or dump one period of frames for receive SP's 
     966 * 
     967 * @return true if successful, false otherwise (indicates xrun). 
     968 */ 
     969bool StreamProcessorManager::transferSilence() { 
     970    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring silent period...\n"); 
     971    bool retval=true; 
     972    retval &= transferSilence(StreamProcessor::ePT_Receive); 
     973    retval &= transferSilence(StreamProcessor::ePT_Transmit); 
     974    return retval; 
     975
     976 
     977/** 
     978 * @brief Transfer one period of silence for either the receive or transmit StreamProcessors 
     979 * 
     980 * Transfers one period of silence to the Iso side for transmit SP's 
     981 * or dump one period of frames for receive SP's 
     982 * 
     983 * @param t The processor type to tranfer for (receive or transmit) 
     984 * @return true if successful, false otherwise (indicates xrun). 
     985 */ 
     986bool StreamProcessorManager::transferSilence(enum StreamProcessor::eProcessorType t) { 
     987    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "transferSilence(%d) at TS=%011llu (%03us %04uc %04ut)...\n",  
     988        t, m_time_of_transfer, 
     989        (unsigned int)TICKS_TO_SECS(m_time_of_transfer), 
     990        (unsigned int)TICKS_TO_CYCLES(m_time_of_transfer), 
     991        (unsigned int)TICKS_TO_OFFSET(m_time_of_transfer)); 
     992 
     993    bool retval = true; 
     994    // a static cast could make sure that there is no performance 
     995    // penalty for the virtual functions (to be checked) 
     996    if (t==StreamProcessor::ePT_Receive) { 
     997        for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     998                it != m_ReceiveProcessors.end(); 
     999                ++it ) { 
     1000            if(!(*it)->dropFrames(m_period, m_time_of_transfer)) { 
     1001                    debugWarning("could not dropFrames(%u, %11llu) from stream processor (%p)\n", 
     1002                            m_period, m_time_of_transfer,*it); 
     1003                retval &= false; // buffer underrun 
     1004            } 
     1005        } 
     1006    } else { 
     1007        // FIXME: in the SPM it would be nice to have system time instead of 
     1008        //        1394 time 
     1009        float rate = m_SyncSource->getTicksPerFrame(); 
     1010        int64_t one_ringbuffer_in_ticks=(int64_t)(((float)(m_nb_buffers * m_period)) * rate); 
     1011 
     1012        // the data we are putting into the buffer is intended to be transmitted 
     1013        // one ringbuffer size after it has been received 
     1014        int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks); 
     1015 
     1016        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     1017                it != m_TransmitProcessors.end(); 
     1018                ++it ) { 
     1019            // FIXME: in the SPM it would be nice to have system time instead of 
     1020            //        1394 time 
     1021            if(!(*it)->putSilenceFrames(m_period, transmit_timestamp)) { 
     1022                debugWarning("could not putSilenceFrames(%u,%llu) to stream processor (%p)\n", 
     1023                        m_period, transmit_timestamp, *it); 
     1024                retval &= false; // buffer underrun 
     1025            } 
     1026        } 
     1027    } 
     1028    return retval; 
    9641029} 
    9651030 
  • trunk/libffado/src/libstreaming/StreamProcessorManager.h

    r445 r734  
    2525#define __FFADO_STREAMPROCESSORMANAGER__ 
    2626 
     27#include "generic/Port.h" 
     28#include "generic/StreamProcessor.h" 
     29#include "util/IsoHandlerManager.h" 
     30 
    2731#include "debugmodule/debugmodule.h" 
    2832#include "libutil/Thread.h" 
    2933#include "libutil/OptionContainer.h" 
    30 #include <semaphore.h> 
    31 #include "Port.h" 
    32 #include "StreamProcessor.h" 
    33 #include "IsoHandlerManager.h" 
    3434 
    3535#include <vector> 
     36#include <semaphore.h> 
    3637 
    3738namespace Streaming { 
     
    5253public: 
    5354 
    54     StreamProcessorManager(unsigned int period, unsigned int nb_buffers); 
     55    StreamProcessorManager(unsigned int period, unsigned int rate, unsigned int nb_buffers); 
    5556    virtual ~StreamProcessorManager(); 
    5657 
     
    6162    bool stop(); 
    6263 
     64    bool startDryRunning(); 
    6365    bool syncStartAll(); 
    6466 
     
    6769    bool unregisterProcessor(StreamProcessor *processor); ///< stop managing a streamprocessor 
    6870 
    69     bool enableStreamProcessors(uint64_t time_to_enable_at); /// enable registered StreamProcessors 
    70     bool disableStreamProcessors(); /// disable registered StreamProcessors 
    71  
    7271    void setPeriodSize(unsigned int period); 
    7372    void setPeriodSize(unsigned int period, unsigned int nb_buffers); 
    74     int getPeriodSize() {return m_period;}; 
     73    unsigned int getPeriodSize() {return m_period;}; 
    7574 
    7675    void setNbBuffers(unsigned int nb_buffers); 
     
    8281 
    8382    // the client-side functions 
     83    bool waitForPeriod(); 
     84    bool transfer(); 
     85    bool transfer(enum StreamProcessor::eProcessorType); 
     86private: 
     87    bool transferSilence(); 
     88    bool transferSilence(enum StreamProcessor::eProcessorType); 
    8489 
    85     bool waitForPeriod(); ///< wait for the next period 
    86  
    87     bool transfer(); ///< transfer the buffer contents from/to client 
    88     bool transfer(enum StreamProcessor::EProcessorType); ///< transfer the buffer contents from/to client (single processor type) 
    89  
     90    bool alignReceivedStreams(); 
     91public: 
    9092    int getDelayedUsecs() {return m_delayed_usecs;}; 
    9193    bool xrunOccurred(); 
    9294    int getXrunCount() {return m_xruns;}; 
     95 
     96    unsigned int getNominalRate() {return m_nominal_framerate;}; 
     97    uint64_t getTimeOfLastTransfer() { return m_time_of_transfer;}; 
    9398 
    9499private: 
     
    116121public: 
    117122    bool setSyncSource(StreamProcessor *s); 
    118     StreamProcessor * getSyncSource(); 
     123    StreamProcessor& getSyncSource() 
     124        {return *m_SyncSource;}; 
    119125 
    120126protected: 
     
    132138    unsigned int m_nb_buffers; 
    133139    unsigned int m_period; 
     140    unsigned int m_nominal_framerate; 
    134141    unsigned int m_xruns; 
    135142 
  • trunk/libffado/src/libutil/StreamStatistics.cpp

    r445 r734  
    2626 
    2727namespace Streaming { 
     28IMPL_DEBUG_MODULE( StreamStatistics, StreamStatistics, DEBUG_LEVEL_VERBOSE ); 
    2829 
    2930StreamStatistics::StreamStatistics() 
     
    3536    , m_sum(0) 
    3637{ 
    37  
    38 
    39  
    40  
    41 StreamStatistics::~StreamStatistics() 
    42 
     38    reset(); 
    4339} 
    4440 
     
    5147} 
    5248 
     49void StreamStatistics::signal(unsigned int val) { 
     50    if (val <= MAX_SIGNAL_VALUE) { 
     51        m_signalled[val]++; 
     52    } 
     53} 
     54 
    5355void StreamStatistics::dumpInfo() { 
    54      printf("--- Stats for %s: min=%ld avg=%f max=%ld cnt=%ld sum=%ld\n",m_name.c_str(), 
    55          m_min,m_average,m_max,m_count,m_sum); 
     56    debugOutputShort( DEBUG_LEVEL_VERBOSE,  
     57                      "--- Stats for %s: min=%ld avg=%f max=%ld cnt=%ld sum=%ld\n", 
     58                      m_name.c_str(), m_min, m_average, m_max, m_count, m_sum); 
     59    debugOutputShort( DEBUG_LEVEL_VERBOSE, "    Signal stats\n"); 
     60    for (unsigned int i=0;i <= MAX_SIGNAL_VALUE; i++) { 
     61        debugOutputShort(DEBUG_LEVEL_VERBOSE,  
     62                         "     Stats for %3u: %8u\n", 
     63                         i, m_signalled[i]); 
     64    } 
    5665} 
    5766 
     
    6271    m_max=0; 
    6372    m_sum=0; 
     73 
     74    for (unsigned int i=0;i <= MAX_SIGNAL_VALUE; i++) { 
     75        m_signalled[i]=0; 
     76    } 
    6477} 
    6578 
  • trunk/libffado/src/libutil/StreamStatistics.h

    r445 r734  
    2727#include <string> 
    2828 
     29#include "debugmodule/debugmodule.h" 
     30 
     31#define MAX_SIGNAL_VALUE 7 
    2932namespace Streaming { 
    3033 
     
    3336    StreamStatistics(); 
    3437 
    35     ~StreamStatistics()
     38    ~StreamStatistics() {}
    3639 
    3740    void setName(std::string n) {m_name=n;}; 
     
    5053    long m_sum; 
    5154 
     55    // some tools to do run statistics 
     56    // will keep a histogram of the number of times a certain value 
     57    // is added. 
     58    void signal(unsigned int val); 
     59 
     60    unsigned int m_signalled[MAX_SIGNAL_VALUE+1]; 
     61 
    5262private: 
    53  
     63    DECLARE_DEBUG_MODULE; 
    5464}; 
    5565 
  • trunk/libffado/src/libutil/TimestampedBuffer.cpp

    r512 r734  
    2828 
    2929#include "libutil/Atomic.h" 
    30 #include "libstreaming/cycletimer.h" 
     30#include "libstreaming/util/cycletimer.h" 
    3131 
    3232#include "TimestampedBuffer.h" 
     
    4545#define DLL_COEFF_C   (DLL_OMEGA * DLL_OMEGA) 
    4646 
     47#define ENTER_CRITICAL_SECTION { \ 
     48    pthread_mutex_lock(&m_framecounter_lock); \ 
     49    } 
     50#define EXIT_CRITICAL_SECTION { \ 
     51    pthread_mutex_unlock(&m_framecounter_lock); \ 
     52    } 
     53 
    4754namespace Util { 
    4855 
     
    5360      m_event_size(0), m_events_per_frame(0), m_buffer_size(0), 
    5461      m_bytes_per_frame(0), m_bytes_per_buffer(0), 
     62      m_enabled( false ), m_transparent ( true ), 
    5563      m_wrap_at(0xFFFFFFFFFFFFFFFFLLU), 
    5664      m_Client(c), m_framecounter(0), 
     
    122130    ffado_timestamp_t diff; 
    123131     
    124     pthread_mutex_lock(&m_framecounter_lock)
     132    ENTER_CRITICAL_SECTION
    125133    diff=m_buffer_next_tail_timestamp - m_buffer_tail_timestamp; 
    126     pthread_mutex_unlock(&m_framecounter_lock)
     134    EXIT_CRITICAL_SECTION
    127135     
    128136    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"getRate: %f/%f=%f\n", 
     
    139147        diff += m_wrap_at; 
    140148    } 
    141      
     149 
    142150    float rate=((float)diff)/((float) m_update_period); 
     151    if (rate<0.0) debugError("rate < 0! (%f)\n",rate); 
    143152    if (fabsf(m_nominal_rate - rate)>(m_nominal_rate*0.1)) { 
    144153        debugWarning("(%p) rate (%10.5f) more that 10%% off nominal (rate=%10.5f, diff="TIMESTAMP_FORMAT_SPEC", update_period=%d)\n", 
    145154                     this, rate,m_nominal_rate,diff, m_update_period); 
    146         dumpInfo(); 
     155 
    147156        return m_nominal_rate; 
    148157    } else { 
     
    208217    // of the new offset.  Doing so certainly makes for a smoother MOTU 
    209218    // startup. 
    210     pthread_mutex_lock(&m_framecounter_lock)
     219    ENTER_CRITICAL_SECTION
    211220    m_buffer_tail_timestamp = m_buffer_tail_timestamp - m_tick_offset + nticks; 
    212221    m_buffer_next_tail_timestamp = (ffado_timestamp_t)((double)m_buffer_tail_timestamp + m_dll_e2); 
    213222    m_tick_offset=nticks; 
    214     pthread_mutex_unlock(&m_framecounter_lock)
     223    EXIT_CRITICAL_SECTION
    215224 
    216225    return true; 
     
    225234 * 
    226235 * In order to get the number of frames in the buffer, use the 
    227  * getFrameCounter, getBufferHeadTimestamp, getBufferTailTimestamp 
     236 * getBufferHeadTimestamp, getBufferTailTimestamp 
    228237 * functions 
    229238 * 
     
    257266 * @return true if successful 
    258267 */ 
    259 bool TimestampedBuffer::reset() { 
     268bool TimestampedBuffer::clearBuffer() { 
     269    debugOutput(DEBUG_LEVEL_VERBOSE, "Clearing buffer\n"); 
    260270    ffado_ringbuffer_reset(m_event_buffer); 
    261  
    262271    resetFrameCounter(); 
    263  
    264272    return true; 
    265273} 
     
    348356     
    349357    // increment without updating the DLL 
    350     pthread_mutex_lock(&m_framecounter_lock)
     358    ENTER_CRITICAL_SECTION
    351359    m_framecounter++; 
    352     pthread_mutex_unlock(&m_framecounter_lock)
     360    EXIT_CRITICAL_SECTION
    353361     
    354362    return true; 
     
    370378    unsigned int write_size=nframes*m_event_size*m_events_per_frame; 
    371379 
     380    if (m_transparent) { 
     381        // while disabled, we don't update the DLL, nor do we write frames 
     382        // we just set the correct timestamp for the frames 
     383        setBufferTailTimestamp(ts); 
     384    } else { 
     385        // add the data payload to the ringbuffer 
     386        size_t written = ffado_ringbuffer_write(m_event_buffer, data, write_size); 
     387        if (written < write_size) 
     388        { 
     389            debugWarning("ringbuffer full, %u, %u\n", write_size, written); 
     390            return false; 
     391        } 
     392        incrementFrameCounter(nframes,ts); 
     393    } 
     394    return true; 
     395} 
     396 
     397/** 
     398 * @brief Preload frames into the buffer 
     399 * 
     400 * Preload \ref nframes of frames from the buffer pointed to by \ref data to the 
     401 * internal ringbuffer. Does not care about transparency. Keeps the buffer head or tail 
     402 * timestamp constant. 
     403 * 
     404 * @note not thread safe 
     405 * 
     406 * @param nframes number of frames to copy 
     407 * @param data pointer to the frame buffer 
     408 * @param keep_head_ts if true, keep the head timestamp constant. If false, keep the 
     409 *                     tail timestamp constant. 
     410 * @return true if successful 
     411 */ 
     412bool TimestampedBuffer::preloadFrames(unsigned int nframes, char *data, bool keep_head_ts) { 
     413    unsigned int write_size = nframes * m_event_size * m_events_per_frame; 
    372414    // add the data payload to the ringbuffer 
    373     if (ffado_ringbuffer_write(m_event_buffer,data,write_size) < write_size) 
     415    size_t written = ffado_ringbuffer_write(m_event_buffer, data, write_size); 
     416    if (written < write_size) 
    374417    { 
    375 //         debugWarning("writeFrames buffer overrun\n"); 
     418        debugWarning("ringbuffer full, request: %u, actual: %u\n", write_size, written); 
    376419        return false; 
    377420    } 
    378  
    379     incrementFrameCounter(nframes,ts); 
    380  
    381     return true; 
    382  
    383 
     421     
     422    // make sure the head timestamp remains identical 
     423    signed int fc; 
     424    ffado_timestamp_t ts; 
     425 
     426    if (keep_head_ts) { 
     427        getBufferHeadTimestamp(&ts, &fc); 
     428    } else { 
     429        getBufferTailTimestamp(&ts, &fc); 
     430    } 
     431    // update frame counter 
     432    m_framecounter += nframes; 
     433    if (keep_head_ts) { 
     434        setBufferHeadTimestamp(ts); 
     435    } else { 
     436        setBufferTailTimestamp(ts); 
     437    } 
     438 
     439    return true; 
     440
     441 
     442/** 
     443 * @brief Drop frames from the head of the buffer 
     444 * 
     445 * drops \ref nframes of frames from the head of internal buffer 
     446 * 
     447 * @param nframes number of frames to drop 
     448 * @return true if successful 
     449 */ 
     450bool 
     451TimestampedBuffer::dropFrames(unsigned int nframes) { 
     452    unsigned int read_size = nframes * m_event_size * m_events_per_frame; 
     453    ffado_ringbuffer_read_advance(m_event_buffer, read_size); 
     454    decrementFrameCounter(nframes); 
     455    return true; 
     456
     457 
    384458/** 
    385459 * @brief Read frames from the buffer 
     
    396470    unsigned int read_size=nframes*m_event_size*m_events_per_frame; 
    397471 
    398     // get the data payload to the ringbuffer 
    399     if ((ffado_ringbuffer_read(m_event_buffer,data,read_size)) < read_size) 
    400     { 
    401 //         debugWarning("readFrames buffer underrun\n"); 
    402         return false; 
    403     } 
    404  
    405     decrementFrameCounter(nframes); 
    406  
    407     return true; 
    408  
     472    if (m_transparent) { 
     473        return true; // FIXME: the data still doesn't make sense! 
     474    } else { 
     475        // get the data payload to the ringbuffer 
     476        if ((ffado_ringbuffer_read(m_event_buffer,data,read_size)) < read_size) 
     477        { 
     478            debugWarning("readFrames buffer underrun\n"); 
     479            return false; 
     480        } 
     481        decrementFrameCounter(nframes); 
     482    } 
     483    return true; 
    409484} 
    410485 
     
    453528 
    454529        if(vec[0].len==0) { // this indicates a full event buffer 
    455             debugError("Event buffer overrun in buffer %p\n",this); 
    456             break; 
     530            debugError("Event buffer overrun in buffer %p, fill: %u, bytes2write: %u \n", 
     531                       this, ffado_ringbuffer_read_space(m_event_buffer), bytes2write); 
     532            debugShowBackLog(); 
     533            return false; 
    457534        } 
    458535 
     
    651728#endif 
    652729 
    653     pthread_mutex_lock(&m_framecounter_lock)
     730    ENTER_CRITICAL_SECTION
    654731 
    655732    m_buffer_tail_timestamp = ts; 
     
    658735    m_buffer_next_tail_timestamp = (ffado_timestamp_t)((double)m_buffer_tail_timestamp + m_dll_e2); 
    659736 
    660     pthread_mutex_unlock(&m_framecounter_lock)
    661  
    662     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Set buffer tail timestamp for (%p) to " 
     737    EXIT_CRITICAL_SECTION
     738 
     739    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "for (%p) to " 
    663740                                          TIMESTAMP_FORMAT_SPEC" => "TIMESTAMP_FORMAT_SPEC", NTS=" 
    664741                                          TIMESTAMP_FORMAT_SPEC", DLL2=%f, RATE=%f\n", 
    665                 this, new_timestamp, ts, m_buffer_next_tail_timestamp, m_dll_e2, m_nominal_rate); 
     742                this, new_timestamp, ts, m_buffer_next_tail_timestamp, m_dll_e2, getRate()); 
    666743 
    667744} 
     
    687764#endif 
    688765 
    689     ffado_timestamp_t ts=new_timestamp; 
    690  
    691     pthread_mutex_lock(&m_framecounter_lock)
     766    ffado_timestamp_t ts = new_timestamp; 
     767 
     768    ENTER_CRITICAL_SECTION
    692769 
    693770    // add the time 
     
    705782    m_buffer_next_tail_timestamp = (ffado_timestamp_t)((double)m_buffer_tail_timestamp + m_dll_e2); 
    706783 
    707     pthread_mutex_unlock(&m_framecounter_lock)
    708  
    709     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Set buffer head timestamp for (%p) to "TIMESTAMP_FORMAT_SPEC" => " 
     784    EXIT_CRITICAL_SECTION
     785 
     786    debugOutput(DEBUG_LEVEL_VERBOSE, "for (%p) to "TIMESTAMP_FORMAT_SPEC" => " 
    710787                                          TIMESTAMP_FORMAT_SPEC", NTS="TIMESTAMP_FORMAT_SPEC", DLL2=%f, RATE=%f\n", 
    711                 this, new_timestamp, ts, m_buffer_next_tail_timestamp, m_dll_e2, m_nominal_rate); 
    712  
     788                this, new_timestamp, ts, m_buffer_next_tail_timestamp, m_dll_e2, getRate()); 
     789 
     790
     791 
     792/** 
     793 * @brief Synchronize the buffer head to a specified timestamp 
     794 * 
     795 * Try to synchronize the buffer head to a specific timestamp. This 
     796 * can mean adding or removing samples to/from the buffer such that 
     797 * the buffer head aligns with the specified timestamp. The alignment 
     798 * is within ts +/- Tsample/2 
     799 * 
     800 * @param target the timestamp to align to 
     801 * @return true if alignment succeeded, false if not  
     802 */ 
     803bool 
     804TimestampedBuffer::syncBufferHeadToTimestamp(ffado_timestamp_t target) 
     805
     806    uint64_t ts_head; 
     807    uint64_t ts_target=(uint64_t)target; 
     808    signed int fc; 
     809    int32_t lag_ticks; 
     810    float lag_frames; 
     811 
     812    ffado_timestamp_t ts_head_tmp; 
     813    getBufferHeadTimestamp(&ts_head_tmp, &fc); 
     814    ts_head=(uint64_t)ts_head_tmp; 
     815    // if target > ts_head then the wanted buffer head timestamp 
     816    // is later than the actual. This means that we (might) have to drop 
     817    // some frames. 
     818    lag_ticks=diffTicks(ts_target, ts_head); 
     819    float rate=getRate(); 
     820     
     821    assert(rate!=0.0); 
     822 
     823    lag_frames=(((float)lag_ticks)/rate); 
     824     
     825    debugOutput( DEBUG_LEVEL_VERBOSE, "(%p): HEAD=%llu, TS=%llu, diff=%ld = %10.5f frames (rate=%10.5f)\n", 
     826                                      this, ts_head, ts_target, lag_ticks, lag_frames, rate); 
     827 
     828    if (lag_frames>=1.0) { 
     829        // the buffer head is too early 
     830        // ditch frames until the buffer head is on time 
     831        char dummy[getBytesPerFrame()]; // one frame of garbage 
     832        int frames_to_ditch=(int)roundf(lag_frames); 
     833        debugOutput( DEBUG_LEVEL_VERBOSE, "(%p): ditching %d frames (@ ts=%lld)\n",this,frames_to_ditch,ts_target); 
     834         
     835        while (frames_to_ditch--) { 
     836            readFrames(1, dummy); 
     837        } 
     838         
     839    } else if (lag_frames<=-1.0) { 
     840        // the buffer head is too late 
     841        // add some padding frames 
     842        int frames_to_add=(int)roundf(lag_frames); 
     843        debugOutput( DEBUG_LEVEL_VERBOSE, "(%p): adding %d frames (@ ts=%lld)\n",this,-frames_to_add,ts_target); 
     844         
     845        while (frames_to_add++) { 
     846             writeDummyFrame(); 
     847        } 
     848    } 
     849    getBufferHeadTimestamp(&ts_head_tmp, &fc); 
     850    ts_head=(uint64_t)ts_head_tmp; 
     851    debugOutput( DEBUG_LEVEL_VERBOSE, "(%p): new HEAD=%llu, fc=%d, target=%llu, new diff=%lld\n", 
     852                                      this, ts_head, fc, ts_target, diffTicks(ts_target, ts_head)); 
     853    // FIXME: of course this doesn't always succeed 
     854    return true; 
     855
     856 
     857/** 
     858 * @brief Synchronize the buffer tail to a specified timestamp 
     859 * 
     860 * Try to synchronize the buffer tail to a specific timestamp. This 
     861 * can mean adding or removing samples to/from the buffer such that 
     862 * the buffer tail aligns with the specified timestamp. The alignment 
     863 * is within ts +/- Tsample/2 
     864 * 
     865 * @param target the timestamp to align to 
     866 * @return true if alignment succeeded, false if not  
     867 */ 
     868bool 
     869TimestampedBuffer::syncBufferTailToTimestamp(ffado_timestamp_t target) 
     870
     871    uint64_t ts_tail; 
     872    uint64_t ts_target=(uint64_t)target; 
     873    signed int fc; 
     874    int32_t lag_ticks; 
     875    float lag_frames; 
     876 
     877    debugWarning("Untested\n"); 
     878     
     879    ffado_timestamp_t ts_tail_tmp; 
     880    getBufferTailTimestamp(&ts_tail_tmp, &fc); 
     881    ts_tail=(uint64_t)ts_tail_tmp; 
     882    // if target < ts_tail then the wanted buffer head timestamp 
     883    // is later than the actual. This means that we (might) have to drop 
     884    // some frames. 
     885    lag_ticks=diffTicks(ts_tail, ts_target); 
     886    float rate=getRate(); 
     887     
     888    assert(rate!=0.0); 
     889 
     890    lag_frames=(((float)lag_ticks)/rate); 
     891     
     892    debugOutput( DEBUG_LEVEL_VERBOSE, "(%p): HEAD=%llu, TS=%llu, diff=%ld = %10.5f frames (rate=%10.5f)\n", 
     893                                      this, ts_tail, ts_target, lag_ticks, lag_frames, rate); 
     894 
     895    if (lag_frames>=1.0) { 
     896        // the buffer head is too early 
     897        // ditch frames until the buffer head is on time 
     898        char dummy[getBytesPerFrame()]; // one frame of garbage 
     899        int frames_to_ditch=(int)roundf(lag_frames); 
     900        debugOutput( DEBUG_LEVEL_VERBOSE, "(%p): ditching %d frames (@ ts=%lld)\n",this,frames_to_ditch,ts_target); 
     901         
     902        while (frames_to_ditch--) { 
     903            readFrames(1, dummy); 
     904        } 
     905         
     906    } else if (lag_frames<=-1.0) { 
     907        // the buffer head is too late 
     908        // add some padding frames 
     909        int frames_to_add=(int)roundf(lag_frames); 
     910        debugOutput( DEBUG_LEVEL_VERBOSE, "(%p): adding %d frames (@ ts=%lld)\n",this,-frames_to_add,ts_target); 
     911         
     912        while (frames_to_add++) { 
     913             writeDummyFrame(); 
     914        } 
     915    } 
     916    getBufferHeadTimestamp(&ts_tail_tmp, &fc); 
     917    ts_tail=(uint64_t)ts_tail_tmp; 
     918    debugOutput( DEBUG_LEVEL_VERBOSE, "(%p): new HEAD=%llu, fc=%d, target=%llu, new diff=%lld\n", 
     919                                      this, ts_tail, fc, ts_target, diffTicks(ts_target, ts_tail)); 
     920    // FIXME: of course this doesn't always succeed 
     921    return true; 
     922
     923 
     924/** 
     925 * @brief correct lag 
     926 * 
     927 * Try to synchronize the buffer tail to a specific timestamp. This 
     928 * can mean adding or removing samples to/from the buffer such that 
     929 * the buffer tail aligns with the specified timestamp. The alignment 
     930 * is within ts +/- Tsample/2 
     931 * 
     932 * @param target the timestamp to align to 
     933 * @return true if alignment succeeded, false if not  
     934 */ 
     935bool 
     936TimestampedBuffer::syncCorrectLag(int64_t lag_ticks) 
     937
     938    float lag_frames; 
     939    float rate=getRate(); 
     940    assert(rate!=0.0); 
     941 
     942    lag_frames=(((float)lag_ticks)/rate); 
     943    if (lag_frames >= 1.0) { 
     944        // the buffer head is too late 
     945        // add some padding frames 
     946        int frames_to_add=(int)roundf(lag_frames); 
     947        debugOutput( DEBUG_LEVEL_VERBOSE, "(%p): adding %d frames\n",this,frames_to_add); 
     948 
     949        while (frames_to_add++) { 
     950             writeDummyFrame(); 
     951        } 
     952    } else if (lag_frames <= -1.0) { 
     953        // the buffer head is too early 
     954        // ditch frames until the buffer head is on time 
     955        char dummy[getBytesPerFrame()]; // one frame of garbage 
     956        int frames_to_ditch=(int)roundf(lag_frames); 
     957        debugOutput( DEBUG_LEVEL_VERBOSE, "(%p): ditching %d frames\n",this,-frames_to_ditch); 
     958 
     959        while (frames_to_ditch--) { 
     960            readFrames(1, dummy); 
     961        } 
     962    } 
     963    return true; 
    713964} 
    714965 
     
    741992 */ 
    742993void TimestampedBuffer::getBufferTailTimestamp(ffado_timestamp_t *ts, signed int *fc) { 
    743     pthread_mutex_lock(&m_framecounter_lock)
     994    ENTER_CRITICAL_SECTION
    744995    *fc = m_framecounter; 
    745996    *ts = m_buffer_tail_timestamp; 
    746     pthread_mutex_unlock(&m_framecounter_lock)
     997    EXIT_CRITICAL_SECTION
    747998} 
    748999 
     
    7641015    ffado_timestamp_t timestamp; 
    7651016     
    766     pthread_mutex_lock(&m_framecounter_lock)
    767      
     1017    ENTER_CRITICAL_SECTION
     1018 
    7681019    diff=m_buffer_next_tail_timestamp - m_buffer_tail_timestamp; 
    7691020    timestamp=m_buffer_tail_timestamp; 
    7701021     
    771     pthread_mutex_unlock(&m_framecounter_lock)
     1022    EXIT_CRITICAL_SECTION
    7721023     
    7731024    if (diff < 0) diff += m_wrap_at; 
     
    8041055 */ 
    8051056void TimestampedBuffer::resetFrameCounter() { 
    806     pthread_mutex_lock(&m_framecounter_lock)
     1057    ENTER_CRITICAL_SECTION
    8071058    m_framecounter = 0; 
    808     pthread_mutex_unlock(&m_framecounter_lock)
     1059    EXIT_CRITICAL_SECTION
    8091060} 
    8101061 
     
    8151066 */ 
    8161067void TimestampedBuffer::decrementFrameCounter(int nbframes) { 
    817     pthread_mutex_lock(&m_framecounter_lock)
     1068    ENTER_CRITICAL_SECTION
    8181069    m_framecounter -= nbframes; 
    819     pthread_mutex_unlock(&m_framecounter_lock)
     1070    EXIT_CRITICAL_SECTION
    8201071} 
    8211072 
     
    8351086    ffado_timestamp_t diff; 
    8361087     
    837     pthread_mutex_lock(&m_framecounter_lock)
    838     diff=m_buffer_next_tail_timestamp - m_buffer_tail_timestamp; 
    839     pthread_mutex_unlock(&m_framecounter_lock)
     1088    ENTER_CRITICAL_SECTION
     1089    diff = m_buffer_next_tail_timestamp - m_buffer_tail_timestamp; 
     1090    EXIT_CRITICAL_SECTION
    8401091 
    8411092    if (diff < 0) diff += m_wrap_at; 
     
    8451096#endif 
    8461097 
    847     ffado_timestamp_t ts=new_timestamp; 
     1098    ffado_timestamp_t ts = new_timestamp; 
    8481099    ts += m_tick_offset; 
    8491100 
     
    8541105    } 
    8551106 
    856     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Setting buffer tail timestamp for (%p) to " 
    857                                           TIMESTAMP_FORMAT_SPEC" => "TIMESTAMP_FORMAT_SPEC"\n", 
    858                 this, new_timestamp, ts); 
    859  
    8601107#ifdef DEBUG 
    8611108    if (new_timestamp >= m_wrap_at) { 
    862         debugWarning("timestamp not wrapped: "TIMESTAMP_FORMAT_SPEC"\n",new_timestamp); 
     1109        debugWarning("timestamp not wrapped: "TIMESTAMP_FORMAT_SPEC"\n", new_timestamp); 
    8631110    } 
    8641111    if ((ts >= m_wrap_at) || (ts < 0 )) { 
     
    8681115// FIXME: JMW: at some points during startup the timestamp doesn't change. 
    8691116// This still needs to be verified in more detail.   
    870 if (ts>m_buffer_tail_timestamp-1 && ts<m_buffer_tail_timestamp+1) { 
    871   pthread_mutex_lock(&m_framecounter_lock); 
    872   m_framecounter += nbframes; 
    873   pthread_mutex_unlock(&m_framecounter_lock); 
    874   return; 
    875 
    876      
    877     // update the DLL 
    878     pthread_mutex_lock(&m_framecounter_lock); 
    879     diff = ts-m_buffer_next_tail_timestamp; 
    880     pthread_mutex_unlock(&m_framecounter_lock); 
    881  
    882 #ifdef DEBUG 
    883     if ((diff > ((ffado_timestamp_t)1000)) || (diff < ((ffado_timestamp_t)-1000))) { 
    884         debugWarning("(%p) difference rather large: "TIMESTAMP_FORMAT_SPEC", "TIMESTAMP_FORMAT_SPEC", "TIMESTAMP_FORMAT_SPEC"\n", 
    885             this, diff, ts, m_buffer_next_tail_timestamp); 
    886     } 
    887 #endif 
    888  
    889     // idea to implement it for nbframes values that differ from m_update_period: 
    890     // diff = diff * nbframes/m_update_period 
    891     // m_buffer_next_tail_timestamp = m_buffer_tail_timestamp + diff 
     1117// if (ts>m_buffer_tail_timestamp-1 && ts<m_buffer_tail_timestamp+1) { 
     1118//   ENTER_CRITICAL_SECTION; 
     1119//   m_framecounter += nbframes; 
     1120//   EXIT_CRITICAL_SECTION; 
     1121//   return; 
     1122// } 
     1123    ffado_timestamp_t pred_buffer_next_tail_timestamp; 
     1124    if(nbframes == m_update_period) { 
     1125        pred_buffer_next_tail_timestamp = m_buffer_next_tail_timestamp; 
     1126    } else { 
     1127        debugOutput( DEBUG_LEVEL_VERBOSE, 
     1128                     "Number of frames (%u) != update period (%u)\n", 
     1129                     nbframes, m_update_period ); 
     1130        // calculate the predicted timestamp for nframes (instead of m_update_period) 
     1131        // after the previous update. 
     1132        float rel_step = ((float)nbframes)/((float)m_update_period); 
     1133        ENTER_CRITICAL_SECTION; // FIXME: do we need these? 
     1134        ffado_timestamp_t corrected_step = (m_buffer_next_tail_timestamp - m_buffer_tail_timestamp) * rel_step; 
     1135        pred_buffer_next_tail_timestamp = m_buffer_tail_timestamp + corrected_step; 
     1136        EXIT_CRITICAL_SECTION; 
     1137         
     1138        debugOutput( DEBUG_LEVEL_VERBOSE, 
     1139                     "Updated ("TIMESTAMP_FORMAT_SPEC","TIMESTAMP_FORMAT_SPEC") to ("TIMESTAMP_FORMAT_SPEC","TIMESTAMP_FORMAT_SPEC")\n", 
     1140                     m_buffer_tail_timestamp, m_buffer_next_tail_timestamp, 
     1141                     m_buffer_tail_timestamp, pred_buffer_next_tail_timestamp); 
     1142         
     1143    } 
     1144     
     1145    // the difference between the given TS and the one predicted for this time instant 
     1146    // this is the error for the DLL 
     1147    diff = ts - pred_buffer_next_tail_timestamp; 
     1148 
     1149    // check whether the update is within the allowed bounds 
     1150    const float max_deviation = (50.0/100.0); // maximal relative difference considered normal 
     1151    ffado_timestamp_t one_update_step = nbframes * getRate(); 
     1152    ffado_timestamp_t max_abs_diff = one_update_step * (1.0 + max_deviation); 
     1153     
     1154    if (diff > max_abs_diff) { 
     1155        debugWarning("(%p) difference rather large (+): diff="TIMESTAMP_FORMAT_SPEC", max="TIMESTAMP_FORMAT_SPEC", "TIMESTAMP_FORMAT_SPEC", "TIMESTAMP_FORMAT_SPEC"\n", 
     1156            this, diff, max_abs_diff, ts, pred_buffer_next_tail_timestamp); 
     1157//         debugShowBackLogLines(40); 
     1158    } else if (diff < -max_abs_diff) { 
     1159        debugWarning("(%p) difference rather large (-): diff="TIMESTAMP_FORMAT_SPEC", max="TIMESTAMP_FORMAT_SPEC", "TIMESTAMP_FORMAT_SPEC", "TIMESTAMP_FORMAT_SPEC"\n", 
     1160            this, diff, -max_abs_diff, ts, pred_buffer_next_tail_timestamp); 
     1161//         debugShowBackLogLines(40); 
     1162    } 
    8921163 
    8931164    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p): diff="TIMESTAMP_FORMAT_SPEC" ", 
    8941165                this, diff); 
    8951166 
    896     // the maximal difference we can allow (64secs) 
    897     const ffado_timestamp_t max=m_wrap_at/2; 
    898  
    899     if(diff > max) { 
    900         diff -= m_wrap_at; 
    901     } else if (diff < -max) { 
    902         diff += m_wrap_at; 
    903     } 
    904  
    905     float err=diff; 
     1167    double err = diff; 
    9061168 
    9071169    debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "diff2="TIMESTAMP_FORMAT_SPEC" err=%f\n", 
    9081170                    diff, err); 
    9091171    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "B: FC=%10u, TS="TIMESTAMP_FORMAT_SPEC", NTS="TIMESTAMP_FORMAT_SPEC"\n", 
    910                     m_framecounter, m_buffer_tail_timestamp, m_buffer_next_tail_timestamp); 
    911  
    912     pthread_mutex_lock(&m_framecounter_lock)
     1172                    m_framecounter, m_buffer_tail_timestamp, pred_buffer_next_tail_timestamp); 
     1173 
     1174    ENTER_CRITICAL_SECTION
    9131175    m_framecounter += nbframes; 
    9141176 
    915     m_buffer_tail_timestamp=m_buffer_next_tail_timestamp; 
    916     m_buffer_next_tail_timestamp += (ffado_timestamp_t)(m_dll_b * err + m_dll_e2); 
     1177    m_buffer_tail_timestamp = pred_buffer_next_tail_timestamp; 
     1178    m_buffer_next_tail_timestamp = pred_buffer_next_tail_timestamp + (ffado_timestamp_t)(m_dll_b * err + m_dll_e2); 
    9171179//    m_buffer_tail_timestamp=ts; 
    9181180//    m_buffer_next_tail_timestamp += (ffado_timestamp_t)(m_dll_b * err + m_dll_e2); 
    9191181     
    9201182    m_dll_e2 += m_dll_c*err; 
    921      
    922 //     debugOutputShort(DEBUG_LEVEL_VERBOSE, "%p %llu %lld %llu %llu %e %e\n", this, new_timestamp, diff, m_buffer_tail_timestamp, m_buffer_next_tail_timestamp, m_dll_e2, 24576000.0/getRate()); 
     1183 
     1184    EXIT_CRITICAL_SECTION; 
     1185 
     1186    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "tail for (%p) to " 
     1187                                          TIMESTAMP_FORMAT_SPEC" => "TIMESTAMP_FORMAT_SPEC", NTS=" 
     1188                                          TIMESTAMP_FORMAT_SPEC", DLL2=%f, RATE=%f\n", 
     1189                this, new_timestamp, ts, m_buffer_next_tail_timestamp, m_dll_e2, getRate()); 
    9231190 
    9241191    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "U: FC=%10u, TS="TIMESTAMP_FORMAT_SPEC", NTS="TIMESTAMP_FORMAT_SPEC"\n", 
    9251192                    m_framecounter, m_buffer_tail_timestamp, m_buffer_next_tail_timestamp); 
    9261193 
     1194    ENTER_CRITICAL_SECTION; 
    9271195    if (m_buffer_next_tail_timestamp >= m_wrap_at) { 
    9281196        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Unwrapping next tail timestamp: "TIMESTAMP_FORMAT_SPEC"", 
     
    9351203 
    9361204    } 
     1205    EXIT_CRITICAL_SECTION; 
    9371206 
    9381207    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "A: TS="TIMESTAMP_FORMAT_SPEC", NTS="TIMESTAMP_FORMAT_SPEC", DLLe2=%f, RATE=%f\n", 
    9391208                m_buffer_tail_timestamp, m_buffer_next_tail_timestamp, m_dll_e2, rate); 
    9401209 
    941     pthread_mutex_unlock(&m_framecounter_lock); 
    9421210 
    9431211    if(m_buffer_tail_timestamp>=m_wrap_at) { 
     
    9821250    debugOutputShort( DEBUG_LEVEL_NORMAL, "  TimestampedBuffer (%p) info:\n",this); 
    9831251    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Frame counter         : %d\n", m_framecounter); 
     1252    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Events in buffer      : %d\n", getBufferFill()); 
    9841253    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Buffer head timestamp : "TIMESTAMP_FORMAT_SPEC"\n",ts_head); 
    9851254    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Buffer tail timestamp : "TIMESTAMP_FORMAT_SPEC"\n",m_buffer_tail_timestamp); 
  • trunk/libffado/src/libutil/TimestampedBuffer.h

    r554 r734  
    3737// #define TIMESTAMP_FORMAT_SPEC "%012lld" 
    3838 
    39 namespace Util { 
    40  
     39namespace Util 
     40
    4141 
    4242class TimestampedBufferClient; 
    4343 
    4444/** 
    45  * \brief Class implementing a frame buffer that is time-aware 
    46  * 
    47  * This class implements a buffer that is time-aware. Whenever new frames 
    48  * are written to the buffer, the timestamp corresponding to the last frame 
    49  * in the buffer is updated. This allows to calculate the timestamp of any 
    50  * other frame in the buffer. 
    51  * 
    52  * The buffer is a frame buffer, having the following parameters defining 
    53  * it's behaviour: 
    54  * - buff_size: buffer size in frames (setBufferSize()) 
    55  * - events_per_frame: the number of events per frame (setEventsPerFrame()) 
    56  * - event_size: the storage size of the events (in bytes) (setEventSize()) 
    57  * 
    58  * The total size of the buffer (in bytes) is at least 
    59  * buff_size*events_per_frame*event_size. 
    60  * 
    61  * Timestamp tracking is done by requiring that a timestamp is specified every 
    62  * time frames are added to the buffer. In combination with the buffer fill and 
    63  * the frame rate (calculated internally), this allows to calculate the timestamp 
    64  * of any frame in the buffer. In order to initialize the internal data structures, 
    65  * the setNominalRate() and setUpdatePeriod() functions are provided. 
    66  * 
    67  * \note Currently the class only supports fixed size writes of size update_period. 
    68  *       This can change in the future, implementation ideas are already in place. 
    69  * 
    70  * The TimestampedBuffer class is time unit agnostic. It can handle any time unit 
    71  * as long as it fits in a 64 bit unsigned integer. The buffer supports wrapped 
    72  * timestamps using (...). 
    73  * 
    74  * There are two methods of reading and writing to the buffer. 
    75  * 
    76  * The first method uses conventional readFrames() and writeFrames() functions. 
    77  * 
    78  * The second method makes use of the TimestampedBufferClient interface. When a 
    79  * TimestampedBuffer is created, it is required that a TimestampedBufferClient is 
    80  * registered. This client implements the processReadBlock and processWriteBlock 
    81  * functions. These are block processing 'callbacks' that allow zero-copy processing 
    82  * of the buffer contents. In order to initiate block processing, the 
    83  * blockProcessWriteFrames and blockProcessReadFrames functions are provided by 
    84  * TimestampedBuffer. 
    85  * 
    86  */ 
    87 class TimestampedBuffer { 
    88  
    89 public: 
    90  
    91  
    92     TimestampedBuffer(TimestampedBufferClient *); 
    93     virtual ~TimestampedBuffer(); 
    94      
    95     bool writeDummyFrame(); 
    96      
    97     bool writeFrames(unsigned int nbframes, char *data, ffado_timestamp_t ts); 
    98     bool readFrames(unsigned int nbframes, char *data); 
    99  
    100     bool blockProcessWriteFrames(unsigned int nbframes, ffado_timestamp_t ts); 
    101     bool blockProcessReadFrames(unsigned int nbframes); 
    102  
    103     bool init(); 
    104     bool prepare(); 
    105     bool reset(); 
    106  
    107     bool setEventSize(unsigned int s); 
    108     bool setEventsPerFrame(unsigned int s); 
    109     bool setBufferSize(unsigned int s); 
    110     unsigned int getBufferSize() {return m_buffer_size;}; 
    111  
    112     unsigned int getBytesPerFrame() {return m_bytes_per_frame;}; 
    113  
    114     bool setWrapValue(ffado_timestamp_t w); 
    115  
    116     unsigned int getBufferFill(); 
    117  
    118     // timestamp stuff 
    119     int getFrameCounter() {return m_framecounter;}; 
    120  
    121     void getBufferHeadTimestamp(ffado_timestamp_t *ts, signed int *fc); 
    122     void getBufferTailTimestamp(ffado_timestamp_t *ts, signed int *fc); 
    123  
    124     void setBufferTailTimestamp(ffado_timestamp_t new_timestamp); 
    125     void setBufferHeadTimestamp(ffado_timestamp_t new_timestamp); 
    126  
    127     ffado_timestamp_t getTimestampFromTail(int nframes); 
    128     ffado_timestamp_t getTimestampFromHead(int nframes); 
    129  
    130     // buffer offset stuff 
    131     /// return the tick offset value 
    132     ffado_timestamp_t getTickOffset() {return m_tick_offset;}; 
    133  
    134     bool setFrameOffset(int nframes); 
    135     bool setTickOffset(ffado_timestamp_t); 
    136  
    137     // dll stuff 
    138     bool setNominalRate(float r); 
    139     float getRate(); 
    140  
    141     bool setUpdatePeriod(unsigned int t); 
    142  
    143     // misc stuff 
    144     void dumpInfo(); 
    145     void setVerboseLevel(int l) {setDebugLevel(l);}; 
    146  
    147 private: 
    148     void decrementFrameCounter(int nbframes); 
    149     void incrementFrameCounter(int nbframes, ffado_timestamp_t new_timestamp); 
    150     void resetFrameCounter(); 
    151  
    152 protected: 
    153  
    154     ffado_ringbuffer_t * m_event_buffer; 
    155     char* m_cluster_buffer; 
    156  
    157     unsigned int m_event_size; // the size of one event 
    158     unsigned int m_events_per_frame; // the number of events in a frame 
    159     unsigned int m_buffer_size; // the number of frames in the buffer 
    160     unsigned int m_bytes_per_frame; 
    161     unsigned int m_bytes_per_buffer; 
    162  
    163     ffado_timestamp_t m_wrap_at; // value to wrap at 
    164  
    165     TimestampedBufferClient *m_Client; 
    166  
    167     DECLARE_DEBUG_MODULE; 
    168  
    169 private: 
    170     // the framecounter gives the number of frames in the buffer 
    171     signed int m_framecounter; 
    172  
    173     // the offset that define the timing of the buffer 
    174     ffado_timestamp_t m_tick_offset; 
    175  
    176     // the buffer tail timestamp gives the timestamp of the last frame 
    177     // that was put into the buffer 
    178     ffado_timestamp_t   m_buffer_tail_timestamp; 
    179     ffado_timestamp_t   m_buffer_next_tail_timestamp; 
    180  
    181     // this mutex protects the access to the framecounter 
    182     // and the buffer head timestamp. 
    183     pthread_mutex_t m_framecounter_lock; 
    184  
    185     // tracking DLL variables 
     45    * \brief Class implementing a frame buffer that is time-aware 
     46    * 
     47    * This class implements a buffer that is time-aware. Whenever new frames 
     48    * are written to the buffer, the timestamp corresponding to the last frame 
     49    * in the buffer is updated. This allows to calculate the timestamp of any 
     50    * other frame in the buffer. 
     51    * 
     52    * The buffer is a frame buffer, having the following parameters defining 
     53    * it's behaviour: 
     54    * - buff_size: buffer size in frames (setBufferSize()) 
     55    * - events_per_frame: the number of events per frame (setEventsPerFrame()) 
     56    * - event_size: the storage size of the events (in bytes) (setEventSize()) 
     57    * 
     58    * The total size of the buffer (in bytes) is at least 
     59    * buff_size*events_per_frame*event_size. 
     60    * 
     61    * Timestamp tracking is done by requiring that a timestamp is specified every 
     62    * time frames are added to the buffer. In combination with the buffer fill and 
     63    * the frame rate (calculated internally), this allows to calculate the timestamp 
     64    * of any frame in the buffer. In order to initialize the internal data structures, 
     65    * the setNominalRate() and setUpdatePeriod() functions are provided. 
     66    * 
     67    * \note Currently the class only supports fixed size writes of size update_period. 
     68    *       This can change in the future, implementation ideas are already in place. 
     69    * 
     70    * The TimestampedBuffer class is time unit agnostic. It can handle any time unit 
     71    * as long as it fits in a 64 bit unsigned integer. The buffer supports wrapped 
     72    * timestamps using (...). 
     73    * 
     74    * There are two methods of reading and writing to the buffer. 
     75    * 
     76    * The first method uses conventional readFrames() and writeFrames() functions. 
     77    * 
     78    * The second method makes use of the TimestampedBufferClient interface. When a 
     79    * TimestampedBuffer is created, it is required that a TimestampedBufferClient is 
     80    * registered. This client implements the processReadBlock and processWriteBlock 
     81    * functions. These are block processing 'callbacks' that allow zero-copy processing 
     82    * of the buffer contents. In order to initiate block processing, the 
     83    * blockProcessWriteFrames and blockProcessReadFrames functions are provided by 
     84    * TimestampedBuffer. 
     85    * 
     86    */ 
     87class TimestampedBuffer 
     88
     89    public: 
     90        TimestampedBuffer ( TimestampedBufferClient * ); 
     91        virtual ~TimestampedBuffer(); 
     92 
     93        bool writeDummyFrame(); 
     94        bool dropFrames ( unsigned int nbframes ); 
     95 
     96        bool writeFrames ( unsigned int nbframes, char *data, ffado_timestamp_t ts ); 
     97        bool readFrames ( unsigned int nbframes, char *data ); 
     98 
     99        bool preloadFrames ( unsigned int nbframes, char *data, bool keep_head_ts ); 
     100 
     101        bool blockProcessWriteFrames ( unsigned int nbframes, ffado_timestamp_t ts ); 
     102        bool blockProcessReadFrames ( unsigned int nbframes ); 
     103 
     104        bool init(); 
     105        bool prepare(); 
     106        bool clearBuffer(); 
     107 
     108        bool isEnabled() {return m_enabled;}; 
     109        void enable() {m_enabled=true;}; 
     110        void disable() {m_enabled=false;}; 
     111 
     112        bool isTransparent() {return m_transparent;}; 
     113        void setTransparent ( bool v ) {m_transparent=v;}; 
     114 
     115        bool setEventSize ( unsigned int s ); 
     116        bool setEventsPerFrame ( unsigned int s ); 
     117        bool setBufferSize ( unsigned int s ); 
     118        unsigned int getBufferSize() {return m_buffer_size;}; 
     119 
     120        unsigned int getBytesPerFrame() {return m_bytes_per_frame;}; 
     121 
     122        bool setWrapValue ( ffado_timestamp_t w ); 
     123 
     124        unsigned int getBufferFill(); 
     125 
     126        // timestamp stuff 
     127        int getFrameCounter() {return m_framecounter;}; 
     128 
     129        void getBufferHeadTimestamp ( ffado_timestamp_t *ts, signed int *fc ); 
     130        void getBufferTailTimestamp ( ffado_timestamp_t *ts, signed int *fc ); 
     131 
     132        void setBufferTailTimestamp ( ffado_timestamp_t new_timestamp ); 
     133        void setBufferHeadTimestamp ( ffado_timestamp_t new_timestamp ); 
     134 
     135        // sync related, also drops or add frames when necessary 
     136        bool syncBufferHeadToTimestamp ( ffado_timestamp_t ts ); 
     137        bool syncBufferTailToTimestamp ( ffado_timestamp_t ts ); 
     138        bool syncCorrectLag ( int64_t ts ); 
     139 
     140        ffado_timestamp_t getTimestampFromTail ( int nframes ); 
     141        ffado_timestamp_t getTimestampFromHead ( int nframes ); 
     142 
     143        // buffer offset stuff 
     144        /// return the tick offset value 
     145        ffado_timestamp_t getTickOffset() {return m_tick_offset;}; 
     146 
     147        bool setFrameOffset ( int nframes ); 
     148        bool setTickOffset ( ffado_timestamp_t ); 
     149 
     150        // dll stuff 
     151        bool setNominalRate ( float r ); 
     152        float getNominalRate() {return m_nominal_rate;}; 
     153        float getRate(); 
     154 
     155        bool setUpdatePeriod ( unsigned int t ); 
     156 
     157        // misc stuff 
     158        void dumpInfo(); 
     159        void setVerboseLevel ( int l ) {setDebugLevel ( l );}; 
     160 
     161    private: 
     162        void decrementFrameCounter ( int nbframes ); 
     163        void incrementFrameCounter ( int nbframes, ffado_timestamp_t new_timestamp ); 
     164        void resetFrameCounter(); 
     165 
     166    protected: 
     167 
     168        ffado_ringbuffer_t * m_event_buffer; 
     169        char* m_cluster_buffer; 
     170 
     171        unsigned int m_event_size; // the size of one event 
     172        unsigned int m_events_per_frame; // the number of events in a frame 
     173        unsigned int m_buffer_size; // the number of frames in the buffer 
     174        unsigned int m_bytes_per_frame; 
     175        unsigned int m_bytes_per_buffer; 
     176        bool m_enabled; // you can get frames FIXME: rename!! 
     177        bool m_transparent; // the buffer should hold the frames put in it. if true, discards all frames 
     178 
     179        ffado_timestamp_t m_wrap_at; // value to wrap at 
     180 
     181        TimestampedBufferClient *m_Client; 
     182 
     183        DECLARE_DEBUG_MODULE; 
     184 
     185    private: 
     186        // the framecounter gives the number of frames in the buffer 
     187        signed int m_framecounter; 
     188 
     189        // the offset that define the timing of the buffer 
     190        ffado_timestamp_t m_tick_offset; 
     191 
     192        // the buffer tail timestamp gives the timestamp of the last frame 
     193        // that was put into the buffer 
     194        ffado_timestamp_t   m_buffer_tail_timestamp; 
     195        ffado_timestamp_t   m_buffer_next_tail_timestamp; 
     196 
     197        // this mutex protects the access to the framecounter 
     198        // and the buffer head timestamp. 
     199        pthread_mutex_t m_framecounter_lock; 
     200 
     201        // tracking DLL variables 
    186202// JMW: try double for this too 
    187203//    float m_dll_e2; 
    188     double m_dll_e2; 
    189     float m_dll_b; 
    190     float m_dll_c; 
    191  
    192     float m_nominal_rate; 
    193     unsigned int m_update_period; 
     204        double m_dll_e2; 
     205        float m_dll_b; 
     206        float m_dll_c; 
     207 
     208        float m_nominal_rate; 
     209        unsigned int m_update_period; 
    194210}; 
    195211 
    196212/** 
    197  * \brief Interface to be implemented by TimestampedBuffer clients 
    198  */ 
    199 class TimestampedBufferClient { 
     213    * \brief Interface to be implemented by TimestampedBuffer clients 
     214    */ 
     215class TimestampedBufferClient 
     216
    200217    public: 
    201218        TimestampedBufferClient() {}; 
    202219        virtual ~TimestampedBufferClient() {}; 
    203220 
    204         virtual bool processReadBlock(char *data, unsigned int nevents, unsigned int offset)=0; 
    205         virtual bool processWriteBlock(char *data, unsigned int nevents, unsigned int offset)=0; 
     221        virtual bool processReadBlock ( char *data, unsigned int nevents, unsigned int offset ) =0; 
     222        virtual bool processWriteBlock ( char *data, unsigned int nevents, unsigned int offset ) =0; 
    206223 
    207224}; 
  • trunk/libffado/src/maudio/maudio_avdevice.h

    r583 r734  
    3232#include "bebob/bebob_avdevice.h" 
    3333 
    34 #include "libstreaming/AmdtpStreamProcessor.h" 
    35 #include "libstreaming/AmdtpPort.h" 
    36 #include "libstreaming/AmdtpPortInfo.h" 
     34#include "libstreaming/amdtp/AmdtpReceiveStreamProcessor.h" 
     35#include "libstreaming/amdtp/AmdtpTransmitStreamProcessor.h" 
     36#include "libstreaming/amdtp/AmdtpPort.h" 
     37#include "libstreaming/amdtp/AmdtpPortInfo.h" 
    3738 
    3839#include "ffadodevice.h" 
  • trunk/libffado/src/metrichalo/mh_avdevice.h

    r639 r734  
    3030#include "libavc/avc_definitions.h" 
    3131 
    32 // #include "libstreaming/MHStreamProcessor.h" 
     32// #include "libstreaming/mh/MHStreamProcessor.h" 
    3333 
    3434class ConfigRom; 
  • trunk/libffado/src/motu/motu_avdevice.cpp

    r660 r734  
    3232#include "debugmodule/debugmodule.h" 
    3333 
    34 #include "libstreaming/MotuStreamProcessor.h" 
    35 #include "libstreaming/MotuPort.h" 
     34#include "libstreaming/motu/MotuReceiveStreamProcessor.h" 
     35#include "libstreaming/motu/MotuTransmitStreamProcessor.h" 
     36#include "libstreaming/motu/MotuPort.h" 
    3637 
    3738#include "libutil/DelayLockedLoop.h" 
     
    523524 
    524525    m_receiveProcessor=new Streaming::MotuReceiveStreamProcessor( 
    525         m_p1394Service->getPort(), samp_freq, event_size_in); 
     526        m_p1394Service->getPort(), event_size_in); 
    526527 
    527528    // The first thing is to initialize the processor.  This creates the 
     
    593594    // Do the same for the transmit processor 
    594595    m_transmitProcessor=new Streaming::MotuTransmitStreamProcessor( 
    595         m_p1394Service->getPort(), getSamplingFrequency(), event_size_out); 
     596        m_p1394Service->getPort(), event_size_out); 
    596597 
    597598    m_transmitProcessor->setVerboseLevel(getDebugLevel()); 
  • trunk/libffado/src/motu/motu_avdevice.h

    r660 r734  
    3131#include "libavc/avc_definitions.h" 
    3232 
    33 #include "libstreaming/MotuStreamProcessor.h" 
     33#include "libstreaming/motu/MotuReceiveStreamProcessor.h" 
     34#include "libstreaming/motu/MotuTransmitStreamProcessor.h" 
    3435 
    3536#define MOTUFW_BASE_ADDR                0xfffff0000000ULL 
  • trunk/libffado/src/rme/rme_avdevice.h

    r639 r734  
    3131#include "libavc/avc_definitions.h" 
    3232 
    33 // #include "libstreaming/RmeStreamProcessor.h" 
     33// #include "libstreaming/rme/RmeStreamProcessor.h" 
    3434 
    3535class ConfigRom; 
  • trunk/libffado/src/SConscript

    r688 r734  
    4242        libieee1394/ieee1394service.cpp \ 
    4343        libieee1394/IEC61883.cpp \ 
    44         libosc/OscArgument.cpp \ 
    45         libosc/OscClient.cpp \ 
    46         libosc/OscMessage.cpp \ 
    47         libosc/OscNode.cpp \ 
    48         libosc/OscResponse.cpp \ 
    49         libosc/OscServer.cpp \ 
    50         libstreaming/cip.c \ 
    51         libstreaming/IsoHandler.cpp \ 
    52         libstreaming/IsoHandlerManager.cpp \ 
    53         libstreaming/IsoStream.cpp \ 
    54         libstreaming/Port.cpp \ 
    55         libstreaming/PortManager.cpp \ 
    56         libstreaming/StreamProcessor.cpp \ 
    5744        libstreaming/StreamProcessorManager.cpp \ 
     45        libstreaming/util/cip.c \ 
     46        libstreaming/util/IsoHandler.cpp \ 
     47        libstreaming/util/IsoHandlerManager.cpp \ 
     48        libstreaming/generic/StreamProcessor.cpp \ 
     49        libstreaming/generic/IsoStream.cpp \ 
     50        libstreaming/generic/Port.cpp \ 
     51        libstreaming/generic/PortManager.cpp \ 
    5852        libutil/cmd_serialize.cpp \ 
    5953        libutil/DelayLockedLoop.cpp \ 
     
    127121motu_source = env.Split( '\ 
    128122        motu/motu_avdevice.cpp \ 
    129         libstreaming/MotuPort.cpp \ 
    130         libstreaming/MotuPortInfo.cpp \ 
    131         libstreaming/MotuStreamProcessor.cpp \ 
     123        libstreaming/motu/MotuPort.cpp \ 
     124        libstreaming/motu/MotuPortInfo.cpp \ 
     125        libstreaming/motu/MotuReceiveStreamProcessor.cpp \ 
     126        libstreaming/motu/MotuTransmitStreamProcessor.cpp \ 
    132127' ) 
    133128 
     
    151146 
    152147amdtp_source = env.Split( '\ 
    153         libstreaming/AmdtpPort.cpp \ 
    154         libstreaming/AmdtpPortInfo.cpp \ 
    155         libstreaming/AmdtpStreamProcessor.cpp \ 
     148        libstreaming/amdtp/AmdtpPort.cpp \ 
     149        libstreaming/amdtp/AmdtpPortInfo.cpp \ 
     150        libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp \ 
     151        libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp \ 
    156152' ) 
    157153 
     
    196192        libenv.MergeFlags( env['ALSA_FLAGS'] ) 
    197193        libenv.MergeFlags( env['LIBXML26_FLAGS'] ) 
    198         libenv.MergeFlags( env['LIBLO_FLAGS'] ) 
    199194 
    200195#env1.AppendUnique( LINKFLAGS = env.Split("-Wl,-rpath $libdir -Wl,-soname -Wl,libffado.so.1 --version-info=1:0:0") ) 
     
    247242        "test-dll" : "libutil/test-dll.cpp", \ 
    248243        "test-unittests-util" : "libutil/unittests.cpp", \ 
    249         "test-unittests-osc" : "libosc/unittests.cpp" \ 
    250244} 
    251245 
  • trunk/libffado/support/firmware/SConscript

    r689 r734  
    1919    env.MergeFlags( env['ALSA_FLAGS'] ) 
    2020    env.MergeFlags( env['LIBXML26_FLAGS'] ) 
    21     env.MergeFlags( env['LIBLO_FLAGS'] ) 
    2221 
    2322apps = { 
     
    2726 
    2827if env['ENABLE_BEBOB']: 
    29     apps["bridgeco-downloader"] = "bridgeco-downloader.cpp" 
    30     installapps += [ "bridgeco-downloader" ] 
     28    apps["ffado-bridgeco-downloader"] = "bridgeco-downloader.cpp" 
     29    installapps += [ "ffado-bridgeco-downloader" ] 
    3130 
    3231if env['ENABLE_FIREWORKS']: 
    33     apps["fireworks-downloader"] = "fireworks-downloader.cpp" 
    34     installapps += [ "fireworks-downloader" ] 
     32    apps["ffado-fireworks-downloader"] = "fireworks-downloader.cpp" 
     33    installapps += [ "ffado-fireworks-downloader" ] 
    3534 
    3635for app in apps.keys(): 
  • trunk/libffado/support/SConscript

    r688 r734  
    1818# 
    1919 
    20 env.SConscript( dirs=["mixer","firmware"], exports="env" ) 
     20env.SConscript( dirs=["mixer","firmware","dbus"], exports="env" ) 
    2121 
  • trunk/libffado/tests/SConscript

    r663 r734  
    55env = env.Copy() 
    66 
    7 env.PrependUnique( CPPPATH=["#/src", "#/external/dbus/include"] ) 
    8 env.PrependUnique( LIBPATH=[env['build_base']+"src", env['build_base']+"external/dbus"] ) 
    9 env.PrependUnique( LIBS=["ffado", "dbus-c++"] ) 
     7env.PrependUnique( CPPPATH=["#/src"] ) 
     8env.PrependUnique( LIBPATH=[env['build_base']+"src"] ) 
     9env.PrependUnique( LIBS=["ffado"] ) 
    1010 
    1111if not env.GetOption( "clean" ): 
    12         env.MergeFlags( env["DBUS1_FLAGS"] ) 
    1312        env.MergeFlags( env['LIBRAW1394_FLAGS'] ) 
    1413        env.MergeFlags( env['LIBXML26_FLAGS'] ) 
    15  
    16 env.Xml2Cpp_Proxy('controlclient-glue.h', 'control-interface.xml') 
    17 env.Xml2Cpp_Adaptor('controlserver-glue.h', 'control-interface.xml') 
    1814 
    1915# 
     
    2218# 
    2319apps = { 
    24         "test-ffado" : "test-ffado.cpp controlserver.cpp", 
     20        "test-ffado" : "test-ffado.cpp", 
    2521        "test-fw410" : "test-fw410.cpp", 
    2622        "test-avccmd" : "test-avccmd.cpp", 
     
    3329        "test-streamdump" : "test-streamdump.cpp", 
    3430        "test-sytmonitor" : "test-sytmonitor.cpp SytMonitor.cpp", 
    35         "test-dbus" : "test-dbus.cpp controlclient.cpp", 
    36         "test-dbus-server" : "test-dbus-server.cpp controlserver.cpp", 
    3731} 
    3832 
  • trunk/libffado/tests/streaming/test-isohandling.cpp

    r445 r734  
    3535#include <netinet/in.h> 
    3636 
    37 #include "src/libstreaming/IsoHandler.h" 
    38 #include "src/libstreaming/IsoStream.h" 
    39 #include "src/libstreaming/StreamProcessorManager.h" 
    40 #include "src/libstreaming/AmdtpStreamProcessor.h" 
    41 #include "src/libstreaming/IsoHandlerManager.h" 
    4237#include "src/libutil/PosixThread.h" 
    43 #include "src/libstreaming/AmdtpPort.h" 
     38 
     39#include "src/libstreaming/util/IsoHandler.h" 
     40#include "src/libstreaming/util/StreamProcessorManager.h" 
     41#include "src/libstreaming/util/IsoHandlerManager.h" 
     42#include "src/libstreaming/amdtp/AmdtpStreamProcessor.h" 
     43#include "src/libstreaming/amdtp/AmdtpPort.h" 
    4444 
    4545using namespace Streaming; 
    46  
    4746 
    4847int run; 
  • trunk/libffado/tests/SytMonitor.cpp

    r445 r734  
    2424 
    2525#include "SytMonitor.h" 
    26 #include "src/libstreaming/IsoStream.h" 
    2726 
    2827#include <netinet/in.h> 
     
    3635 
    3736SytMonitor::SytMonitor(int port) 
    38     : IsoStream(IsoStream::EST_Receive, port) { 
     37    : IsoStream(IsoStream::eST_Receive, port) { 
    3938    m_cinfo_buffer=ffado_ringbuffer_create(16384*sizeof(struct cycle_info)); 
    4039 
  • trunk/libffado/tests/SytMonitor.h

    r445 r734  
    2525#ifndef __FFADO_SYTMONITOR__ 
    2626#define __FFADO_SYTMONITOR__ 
    27 #include "src/libstreaming/IsoStream.h" 
    28 #include "src/libstreaming/cip.h" 
    29 #include "src/libstreaming/cycletimer.h" 
     27#include "src/libstreaming/generic/IsoStream.h" 
     28#include "src/libstreaming/util/cip.h" 
     29#include "src/libstreaming/util/cycletimer.h" 
    3030#include "src/libutil/ringbuffer.h" 
    3131 
  • trunk/libffado/tests/test-cycletimer.cpp

    r445 r734  
    3737#include <netinet/in.h> 
    3838 
    39 #include "src/libstreaming/cycletimer.h" 
    40  
    41 #include "src/libstreaming/IsoHandler.h" 
    42 #include "src/libstreaming/IsoStream.h" 
    43 #include "src/libstreaming/IsoHandlerManager.h" 
     39#include "src/libstreaming/util/cycletimer.h" 
     40 
     41#include "src/libstreaming/util/IsoHandler.h" 
     42#include "src/libstreaming/generic/IsoStream.h" 
     43#include "src/libstreaming/util/IsoHandlerManager.h" 
    4444#include "src/libutil/PosixThread.h" 
    4545 
     
    288288#ifdef TEST_PORT_0 
    289289    // add a stream to the manager so that it has something to do 
    290     s=new IsoStream(IsoStream::EST_Receive, 0); 
     290    s=new IsoStream(IsoStream::eST_Receive, 0); 
    291291 
    292292    if (!s) { 
     
    296296 
    297297    s->setVerboseLevel(DEBUG_LEVEL_VERBOSE); 
    298  
    299     if (!s->init()) { 
    300         debugOutput(DEBUG_LEVEL_NORMAL, "Could not init IsoStream\n"); 
    301         goto finish; 
    302     } 
    303  
    304298    s->setChannel(0); 
    305299 
  • trunk/libffado/tests/test-ffado.cpp

    r639 r734  
    3636#include "ffadodevice.h" 
    3737 
    38 #include <dbus-c++/dbus.h> 
    39 #include "controlserver.h" 
    40 #include "libcontrol/BasicElements.h" 
    41  
    4238#include <signal.h> 
    4339 
     
    5248#include <sstream> 
    5349 
    54 #include <lo/lo.h> 
    55  
    5650using namespace std; 
    5751 
    5852DECLARE_GLOBAL_DEBUG_MODULE; 
    59  
    60 // prototypes & stuff for listing the OSC space 
    61 void list_osc_paths(lo_server s, lo_address t, const char *path); 
    62 void list_osc_params(lo_server s, lo_address t, const char *path); 
    63 string osc_param_get_value(lo_server s, lo_address t, const char *path, const char *param); 
    64  
    65 vector<string> osc_paths; 
    66 vector<string> osc_params; 
    67 string osc_value; 
    68  
    69 int osc_path_response_handler(const char *path, const char *types, lo_arg **argv, int argc, 
    70     void *data, void *user_data); 
    71  
    72 int osc_param_response_handler(const char *path, const char *types, lo_arg **argv, int argc, 
    73     void *data, void *user_data); 
    74  
    75 int osc_data_response_handler(const char *path, const char *types, lo_arg **argv, int argc, 
    76     void *data, void *user_data); 
    77  
    78 void osc_error_handler(int num, const char *msg, const char *path); 
    79  
    80 // DBUS stuff 
    81 DBus::BusDispatcher dispatcher; 
    82  
    83 // signal handler 
    84 int run=1; 
    85 static void sighandler (int sig) 
    86 { 
    87     run = 0; 
    88     dispatcher.leave(); 
    89 } 
    9053 
    9154// global's 
     
    9861                    "           SetSamplerate samplerate\n" 
    9962                    "           SetClockSource [id]\n" 
    100                     "           ListOscSpace\n" 
    101                     "           OscServer\n" 
    102                     "           DBus\n" 
    10363                    ; 
    10464 
     
    384344        delete m_deviceManager; 
    385345        return exitfunction(0); 
    386     } else if ( strcmp( arguments.args[0], "ListOscSpace" ) == 0 ) { 
    387         // list osc space by using OSC messages 
    388         // a server is assumed to be present 
    389  
    390         /* start a new server. 
    391         when sending a message from this context, the response 
    392         address will be set to this server's address. 
    393         */ 
    394         lo_server s = lo_server_new(NULL, osc_error_handler); 
    395         lo_address t = lo_address_new(NULL, "17820"); 
    396  
    397         list_osc_paths(s, t, "/"); 
    398  
    399         lo_address_free(t); 
    400         lo_server_free(s); 
    401  
    402     } else if ( strcmp( arguments.args[0], "OscServer" ) == 0 ) { 
    403         DeviceManager *m_deviceManager = new DeviceManager(); 
    404         if ( !m_deviceManager ) { 
    405             fprintf( stderr, "Could not allocate device manager\n" ); 
    406             return exitfunction(-1); 
    407         } 
    408         if ( !m_deviceManager->initialize( arguments.port ) ) { 
    409             fprintf( stderr, "Could not initialize device manager\n" ); 
    410             delete m_deviceManager; 
    411             return exitfunction(-1); 
    412         } 
    413         if ( arguments.verbose ) { 
    414             m_deviceManager->setVerboseLevel(arguments.verbose); 
    415         } 
    416         if ( !m_deviceManager->discover() ) { 
    417             fprintf( stderr, "Could not discover devices\n" ); 
    418             delete m_deviceManager; 
    419             return exitfunction(-1); 
    420         } 
    421  
    422         printf("server started\n"); 
    423         printf("press ctrl-c to stop it & continue\n"); 
    424  
    425         signal (SIGINT, sighandler); 
    426  
    427         run=1; 
    428         while(run) { 
    429             sleep(1); 
    430             fflush(stdout); 
    431             fflush(stderr); 
    432         } 
    433         signal (SIGINT, SIG_DFL); 
    434  
    435         printf("server stopped\n"); 
    436         delete m_deviceManager; 
    437         return exitfunction(0); 
    438     } else if ( strcmp( arguments.args[0], "DBus" ) == 0 ) { 
    439         DeviceManager *m_deviceManager = new DeviceManager(); 
    440         if ( !m_deviceManager ) { 
    441             fprintf( stderr, "Could not allocate device manager\n" ); 
    442             return exitfunction(-1); 
    443         } 
    444         if ( !m_deviceManager->initialize( arguments.port ) ) { 
    445             fprintf( stderr, "Could not initialize device manager\n" ); 
    446             delete m_deviceManager; 
    447             return exitfunction(-1); 
    448         } 
    449         if ( arguments.verbose ) { 
    450             m_deviceManager->setVerboseLevel(arguments.verbose); 
    451         } 
    452         if ( !m_deviceManager->discover() ) { 
    453             fprintf( stderr, "Could not discover devices\n" ); 
    454             delete m_deviceManager; 
    455             return exitfunction(-1); 
    456         } 
    457         
    458         signal (SIGINT, sighandler); 
    459          
    460         DBus::_init_threading(); 
    461      
    462         // test DBUS stuff 
    463         DBus::default_dispatcher = &dispatcher; 
    464      
    465         DBus::Connection conn = DBus::Connection::SessionBus(); 
    466         conn.request_name("org.ffado.Control"); 
    467          
    468         DBusControl::Container *container 
    469             = new DBusControl::Container(conn, "/org/ffado/Control/DeviceManager", *m_deviceManager); 
    470          
    471         printf("DBUS test service running\n"); 
    472         printf("press ctrl-c to stop it & continue\n"); 
    473          
    474         dispatcher.enter(); 
    475      
    476         delete container; 
    477  
    478         signal (SIGINT, SIG_DFL); 
    479  
    480         printf("server stopped\n"); 
    481         delete m_deviceManager; 
    482         return exitfunction(0); 
    483     } else { 
    484         printf( "unknown operation\n" ); 
    485346    } 
    486  
    487347} 
    488  
    489 void list_osc_paths(lo_server s, lo_address t, const char *path) { 
    490     vector<string> my_paths; 
    491  
    492     printf("listing path: %s\n", path); 
    493  
    494     osc_paths.clear(); 
    495     lo_server_add_method(s, "/response", NULL, osc_path_response_handler, NULL); 
    496  
    497     if (lo_send(t, path, "s", "list") == -1) { 
    498         printf(" OSC error %d: %s\n", lo_address_errno(t), lo_address_errstr(t)); 
    499     } 
    500  
    501     if (lo_server_recv_noblock(s, 1000) == 0) { 
    502         printf("timeout\n"); 
    503         return; 
    504     } 
    505  
    506     lo_server_del_method(s, "/response", NULL); 
    507  
    508     list_osc_params(s, t, path); 
    509  
    510     my_paths=osc_paths; 
    511     for ( vector<string>::iterator it = my_paths.begin(); 
    512             it != my_paths.end(); 
    513             ++it ) 
    514     { 
    515         string new_path=string(path) + *it; 
    516         new_path += string("/"); 
    517         list_osc_paths(s, t, new_path.c_str()); 
    518     } 
    519  
    520 } 
    521  
    522 void list_osc_params(lo_server s, lo_address t, const char *path) { 
    523     vector<string> my_paths; 
    524     printf("params for: %s\n", path); 
    525  
    526     osc_params.clear(); 
    527     lo_server_add_method(s, "/response", NULL, osc_param_response_handler, NULL); 
    528  
    529     if (lo_send(t, path, "s", "params") == -1) { 
    530         printf(" OSC error %d: %s\n", lo_address_errno(t), lo_address_errstr(t)); 
    531     } 
    532  
    533     if (lo_server_recv_noblock(s, 1000) == 0) { 
    534         printf("timeout\n"); 
    535         return; 
    536     } 
    537  
    538     lo_server_del_method(s, "/response", NULL); 
    539  
    540     vector<string> my_params=osc_params; 
    541  
    542     for ( vector<string>::iterator it = my_params.begin(); 
    543             it != my_params.end(); 
    544             ++it ) 
    545     { 
    546         string value=osc_param_get_value(s, t, path, (*it).c_str()); 
    547         printf("  %20s = %s\n", (*it).c_str(), value.c_str()); 
    548     } 
    549  
    550 } 
    551  
    552 string osc_param_get_value(lo_server s, lo_address t, const char *path, const char *param) { 
    553     lo_server_add_method(s, "/response", NULL, osc_data_response_handler, NULL); 
    554  
    555     if (lo_send(t, path, "ss", "get", param) == -1) { 
    556         printf(" OSC error %d: %s\n", lo_address_errno(t), lo_address_errstr(t)); 
    557     } 
    558  
    559     if (lo_server_recv_noblock(s, 1000) == 0) { 
    560         return string("timeout"); 
    561     } 
    562  
    563     lo_server_del_method(s, "/response", NULL); 
    564     return osc_value; 
    565 } 
    566  
    567 void osc_error_handler(int num, const char *msg, const char *path) 
    568 { 
    569     printf("liblo server error %d in path %s: %s\n", num, path, msg); 
    570 } 
    571  
    572 int osc_path_response_handler(const char *path, const char *types, lo_arg **argv, int argc, 
    573         void *data, void *user_data) 
    574 { 
    575     for (int i=0; i< argc;i++) { 
    576         switch (lo_type(types[i])) { 
    577             /** Standard C, NULL terminated string. */ 
    578             case LO_STRING: 
    579                 osc_paths.push_back(string(&(argv[i]->s))); 
    580                 break; 
    581             default: 
    582                 printf("unexpected data type in response message\n"); 
    583         } 
    584     } 
    585     return 1; 
    586 } 
    587  
    588 int osc_param_response_handler(const char *path, const char *types, lo_arg **argv, int argc, 
    589         void *data, void *user_data) 
    590 { 
    591     for (int i=0; i< argc;i++) { 
    592         switch (lo_type(types[i])) { 
    593             /** Standard C, NULL terminated string. */ 
    594             case LO_STRING: 
    595                 osc_params.push_back(string(&(argv[i]->s))); 
    596                 break; 
    597             default: 
    598                 printf("unexpected data type in response message\n"); 
    599         } 
    600     } 
    601     return 1; 
    602 } 
    603  
    604 int osc_data_response_handler(const char *path, const char *types, lo_arg **argv, int argc, 
    605         void *data, void *user_data) 
    606 { 
    607     std::ostringstream str; 
    608  
    609     if(argc==1) { 
    610         switch (lo_type(types[0])) { 
    611             /* basic OSC types */ 
    612             /** 32 bit signed integer. */ 
    613             case LO_INT32: 
    614                 str << "0x" << std::hex << argv[0]->i; 
    615                 osc_value=str.str(); 
    616                 break; 
    617             case LO_INT64: 
    618                 str << "0x" << std::hex << argv[0]->h; 
    619                 osc_value=str.str(); 
    620                 break; 
    621             /** 32 bit IEEE-754 float. */ 
    622             case LO_FLOAT: 
    623                 str << argv[0]->f; 
    624                 osc_value=str.str(); 
    625                 break; 
    626             /** Standard C, NULL terminated string. */ 
    627             case LO_STRING: 
    628                 osc_value=string(&argv[0]->s); 
    629                 break; 
    630             default: 
    631                 osc_value="unsupported response datatype"; 
    632         } 
    633     } else { 
    634         osc_value="invalid response"; 
    635     } 
    636     return 1; 
    637 } 
  • trunk/libffado/tests/test-sytmonitor.cpp

    r445 r734  
    3737#include <netinet/in.h> 
    3838 
    39 #include "src/libstreaming/cycletimer.h" 
    40  
    41 #include "src/libstreaming/IsoHandlerManager.h" 
     39#include "src/libstreaming/util/cycletimer.h" 
     40 
     41#include "src/libstreaming/util/IsoHandlerManager.h" 
    4242#include "SytMonitor.h" 
    4343 
     
    233233 
    234234            monitors[i]->setVerboseLevel(DEBUG_LEVEL_VERBOSE); 
    235  
    236             if (!monitors[i]->init()) { 
    237                 debugOutput(DEBUG_LEVEL_NORMAL, "Could not init SytMonitor %d\n", i); 
    238                 goto finish; 
    239             } 
    240  
    241235            monitors[i]->setChannel(arguments.args[i].channel); 
    242236 
  • trunk/libffado/tests/test-timestampedbuffer.cpp

    r494 r734  
    3737#include <netinet/in.h> 
    3838 
    39 #include "src/libstreaming/cycletimer.h" 
     39#include "src/libstreaming/util/cycletimer.h" 
    4040 
    4141#include "src/libutil/TimestampedBuffer.h"