Changeset 833

Show
Ignore:
Timestamp:
01/10/08 13:36:13 (15 years ago)
Author:
ppalmers
Message:

merge api-cleanup branch (R808:832) into trunk

Files:

Legend:

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

    r807 r833  
    6767#define STREAMPROCESSORMANAGER_PRESTART_CYCLES_FOR_XMIT     20 
    6868#define STREAMPROCESSORMANAGER_PRESTART_CYCLES_FOR_RECV     0 
     69#define STREAMPROCESSORMANAGER_SYNCSTART_TRIES              10 
     70#define STREAMPROCESSORMANAGER_SYNC_WAIT_TIME_MSEC          200 
    6971#define STREAMPROCESSORMANAGER_ALIGN_AVERAGE_TIME_MSEC      200 
    7072#define STREAMPROCESSORMANAGER_NB_ALIGN_TRIES               40 
  • trunk/libffado/libffado/ffado.h

    r742 r833  
    206206 
    207207/** 
    208  *  
    209  * Buffer types known to the API 
    210  *  
     208 * 
     209 * Audio data types known to the API 
     210 * 
    211211 */ 
    212212typedef enum { 
    213     ffado_buffer_type_per_stream      = -1, // use this to use the per-stream read functions 
    214     ffado_buffer_type_int24           =  0, 
    215     ffado_buffer_type_float           =  1, 
    216     ffado_buffer_type_midi            =  2, 
    217 } ffado_streaming_buffer_type; 
     213    ffado_audio_datatype_error           = -1, 
     214    ffado_audio_datatype_int24           =  0, 
     215    ffado_audio_datatype_float           =  1, 
     216} ffado_streaming_audio_datatype; 
     217 
     218/** 
     219 * 
     220 * Wait responses 
     221 * 
     222 */ 
     223typedef enum { 
     224    ffado_wait_error           = -2, 
     225    ffado_wait_xrun            = -1, 
     226    ffado_wait_ok              =  0, 
     227} ffado_wait_response; 
    218228 
    219229/** 
     
    339349 
    340350int ffado_streaming_set_capture_stream_buffer(ffado_device_t *dev, int number, char *buff); 
    341 int ffado_streaming_set_capture_buffer_type(ffado_device_t *dev, int i, ffado_streaming_buffer_type t); 
    342351int ffado_streaming_capture_stream_onoff(ffado_device_t *dev, int number, int on); 
    343352 
     
    355364 */ 
    356365int ffado_streaming_set_playback_stream_buffer(ffado_device_t *dev, int number, char *buff); 
    357 int ffado_streaming_set_playback_buffer_type(ffado_device_t *dev, int i, ffado_streaming_buffer_type t); 
    358366int ffado_streaming_playback_stream_onoff(ffado_device_t *dev, int number, int on); 
    359367 
     368ffado_streaming_audio_datatype ffado_streaming_get_audio_datatype(ffado_device_t *dev); 
     369int ffado_streaming_set_audio_datatype(ffado_device_t *dev, ffado_streaming_audio_datatype t); 
    360370 
    361371/** 
     
    409419 * @return The number of frames ready. -1 when a problem occurred. 
    410420 */ 
    411 int ffado_streaming_wait(ffado_device_t *dev); 
    412  
    413 /** 
    414  * Reads from a specific channel to a supplied buffer. 
    415  *  
    416  * @param dev the ffado device 
    417  * @param number the stream number 
    418  * @param buffer the buffer to copy the samples into 
    419  * @param nsamples the number of samples to be read. the buffer has to be big enough for this amount of samples. 
    420  * 
    421  * @return the amount of samples actually read. -1 on error (xrun). 
    422  */ 
    423 int ffado_streaming_read(ffado_device_t *dev, int number, ffado_sample_t *buffer, int nsamples); 
    424  
    425 /** 
    426  * Write to a specific channel from a supplied buffer. 
    427  *  
    428  * @param dev the ffado device 
    429  * @param number the stream number 
    430  * @param buffer the buffer to copy the samples from 
    431  * @param nsamples the number of samples to be written. 
    432  * 
    433  * @return the amount of samples actually written. -1 on error. 
    434  */ 
    435 int ffado_streaming_write(ffado_device_t *dev, int number, ffado_sample_t *buffer, int nsamples); 
     421ffado_wait_response ffado_streaming_wait(ffado_device_t *dev); 
    436422 
    437423/** 
  • trunk/libffado/SConstruct

    r823 r833  
    331331        env['REVISION'] = '' 
    332332 
    333 env['FFADO_API_VERSION']="5
     333env['FFADO_API_VERSION']="7
    334334 
    335335env['PACKAGE'] = "libffado" 
    336 env['VERSION'] = "1.999.11
     336env['VERSION'] = "1.999.13
    337337env['LIBVERSION'] = "1.0.0" 
    338338 
  • trunk/libffado/src/bebob/focusrite/focusrite_saffirepro.cpp

    r783 r833  
    231231            "UseHighVoltageRail", "Use High Supply", "Prefer the high voltage power supply rail")); 
    232232 
     233    result &= m_ControlContainer->addElement( 
     234        new SaffireProMultiControl(*this, SaffireProMultiControl::eTCT_ExitStandalone, 
     235            "ExitStandalone", "Exit Standalone mode", "Try to leave standalonbe mode")); 
     236 
     237    result &= m_ControlContainer->addElement( 
     238        new SaffireProMultiControl(*this, SaffireProMultiControl::eTCT_PllLockRange, 
     239            "PllLockRange", "PLL Lock Range", "Get/Set PLL Lock range")); 
     240 
    233241    if (!result) { 
    234242        debugWarning("One or more device control elements could not be created."); 
     
    484492 
    485493void 
     494SaffireProDevice::exitStandalone() { 
     495    debugOutput( DEBUG_LEVEL_VERBOSE, "exit standalone mode...\n" ); 
     496    if ( !setSpecificValue(FR_SAFFIREPRO_CMD_ID_EXIT_STANDALONE,  
     497                           FR_SAFFIREPRO_CMD_EXIT_STANDALONE_CODE ) ) { 
     498        debugError( "setSpecificValue failed\n" ); 
     499    } 
     500} 
     501 
     502void 
    486503SaffireProDevice::flashLed() { 
    487504    int ledFlashDuration=2; 
     
    570587} 
    571588 
     589void 
     590SaffireProDevice::setPllLockRange(unsigned int i) { 
     591    uint32_t reg=i; 
     592    debugOutput( DEBUG_LEVEL_VERBOSE, "set PLL lock range: %d ...\n", i ); 
     593 
     594    if ( !setSpecificValue(FR_SAFFIREPRO_CMD_ID_PLL_LOCK_RANGE,  
     595                           reg ) ) { 
     596        debugError( "setSpecificValue failed\n" ); 
     597    } 
     598} 
     599 
     600unsigned int 
     601SaffireProDevice::getPllLockRange() { 
     602    uint32_t retval; 
     603    if ( !getSpecificValue(FR_SAFFIREPRO_CMD_ID_PLL_LOCK_RANGE, &retval ) ) { 
     604        debugError( "getSpecificValue failed\n" ); 
     605        return false; 
     606    } 
     607 
     608    debugOutput( DEBUG_LEVEL_VERBOSE, 
     609                     "PLL lock range: %d\n", retval ); 
     610    return retval; 
     611} 
     612 
    572613// swiss army knife control element 
    573 SaffireProMultiControl::SaffireProMultiControl(SaffireProDevice& parent, enum eTriggerControlType t) 
     614SaffireProMultiControl::SaffireProMultiControl(SaffireProDevice& parent, enum eMultiControlType t) 
    574615: Control::Discrete() 
    575616, m_Parent(parent) 
    576617, m_type ( t ) 
    577618{} 
    578 SaffireProMultiControl::SaffireProMultiControl(SaffireProDevice& parent, enum eTriggerControlType t, 
     619SaffireProMultiControl::SaffireProMultiControl(SaffireProDevice& parent, enum eMultiControlType t, 
    579620                std::string name, std::string label, std::string descr) 
    580621: Control::Discrete() 
     
    594635        case eTCT_FlashLed: m_Parent.flashLed(); return true; 
    595636        case eTCT_UseHighVoltageRail: m_Parent.useHighVoltageRail(v); return true; 
     637        case eTCT_ExitStandalone: m_Parent.exitStandalone(); return true; 
     638        case eTCT_PllLockRange: m_Parent.setPllLockRange(v); return true; 
    596639    } 
    597640    return false; 
     
    605648        case eTCT_FlashLed: return 0; 
    606649        case eTCT_UseHighVoltageRail: return m_Parent.usingHighVoltageRail(); 
     650        case eTCT_ExitStandalone: return 0; 
     651        case eTCT_PllLockRange: return m_Parent.getPllLockRange(); 
    607652    } 
    608653    return -1; 
  • trunk/libffado/src/bebob/focusrite/focusrite_saffirepro.h

    r750 r833  
    254254{ 
    255255public: 
    256     enum eTriggerControlType { 
     256    enum eMultiControlType { 
    257257        eTCT_Reboot, 
    258258        eTCT_FlashLed, 
    259259        eTCT_UseHighVoltageRail, 
     260        eTCT_ExitStandalone, 
     261        eTCT_PllLockRange, 
    260262    }; 
    261263 
    262264public: 
    263     SaffireProMultiControl(SaffireProDevice& parent, enum eTriggerControlType); 
    264     SaffireProMultiControl(SaffireProDevice& parent, enum eTriggerControlType, 
     265    SaffireProMultiControl(SaffireProDevice& parent, enum eMultiControlType); 
     266    SaffireProMultiControl(SaffireProDevice& parent, enum eMultiControlType, 
    265267                  std::string name, std::string label, std::string descr); 
    266268 
     
    270272private: 
    271273    SaffireProDevice&          m_Parent; 
    272     enum eTriggerControlType  m_type; 
     274    enum eMultiControlType  m_type; 
    273275}; 
    274276 
     
    320322    bool isExtClockLocked(); 
    321323    uint32_t getCount32(); 
     324    void exitStandalone(); 
    322325 
    323326    void useHighVoltageRail(bool useIt); 
    324327    bool usingHighVoltageRail(); 
     328    unsigned int getPllLockRange(); 
     329    void setPllLockRange(unsigned int); 
     330 
    325331private: 
    326332    virtual bool setSamplingFrequencyDo( uint32_t ); 
  • trunk/libffado/src/bounce/bounce_avdevice.cpp

    r742 r833  
    212212        Streaming::Port *p=NULL; 
    213213        p=new Streaming::AmdtpAudioPort( 
     214                *processor, 
    214215                buff, 
    215216                direction, 
     
    224225        if (!p) { 
    225226            debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",buff); 
    226         } else { 
    227  
    228             if (!processor->addPort(p)) { 
    229                 debugWarning("Could not register port with stream processor\n"); 
    230                 free(buff); 
    231                 return false; 
    232             } else { 
    233                 debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",buff); 
    234             } 
    235227        } 
    236228        free(buff); 
     
    243235        Streaming::Port *p=NULL; 
    244236        p=new Streaming::AmdtpMidiPort( 
     237                *processor, 
    245238                buff, 
    246239                direction, 
     
    255248        if (!p) { 
    256249            debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",buff); 
    257         } else { 
    258  
    259             if (!processor->addPort(p)) { 
    260                 debugWarning("Could not register port with stream processor\n"); 
    261                 free(buff); 
    262                 return false; 
    263             } else { 
    264                 debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",buff); 
    265             } 
    266250        } 
    267251        free(buff); 
  • trunk/libffado/src/devicemanager.cpp

    r826 r833  
    553553} 
    554554 
    555 bool 
     555enum DeviceManager::eWaitResult 
    556556DeviceManager::waitForPeriod() { 
    557557    if(m_processorManager->waitForPeriod()) { 
    558         return true
     558        return eWR_OK
    559559    } else { 
    560560        debugWarning("XRUN detected\n"); 
    561561        // do xrun recovery 
    562562        if(m_processorManager->handleXrun()) { 
    563             return false
     563            return eWR_Xrun
    564564        } else { 
    565565            debugError("Could not handle XRUN\n"); 
    566             return false
     566            return eWR_Error
    567567        } 
    568568    } 
  • trunk/libffado/src/devicemanager.h

    r826 r833  
    6161{ 
    6262public: 
     63    enum eWaitResult { 
     64        eWR_OK, 
     65        eWR_Xrun, 
     66        eWR_Error, 
     67    }; 
     68 
    6369    DeviceManager(); 
    6470    ~DeviceManager(); 
     
    7985    bool stopStreaming(); 
    8086    bool resetStreaming(); 
    81     bool waitForPeriod(); 
     87    enum eWaitResult waitForPeriod(); 
    8288    bool setStreamingParams(unsigned int period, unsigned int rate, unsigned int nb_buffers); 
    8389 
  • trunk/libffado/src/dice/dice_avdevice.cpp

    r785 r833  
    839839    case ePT_Analog: 
    840840        p=new Streaming::AmdtpAudioPort( 
     841                *processor, 
    841842                portname.str(), 
    842843                direction, 
     
    849850    case ePT_MIDI: 
    850851        p=new Streaming::AmdtpMidiPort( 
     852                *processor, 
    851853                portname.str(), 
    852854                direction, 
     
    864866    if (!p) { 
    865867        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->name.c_str()); 
    866     } else { 
    867  
    868         if (!processor->addPort(p)) { 
    869             debugWarning("Could not register port with stream processor\n"); 
    870             return false; 
    871         } 
    872868    } 
    873869 
  • trunk/libffado/src/ffado.cpp

    r807 r833  
    184184    if(!dev->m_deviceManager->prepareStreaming()) { 
    185185        debugFatal("Could not prepare the streaming system\n"); 
    186         return 0
     186        return -1
    187187    } 
    188188    return 0; 
     
    226226} 
    227227 
    228 int ffado_streaming_wait(ffado_device_t *dev) { 
     228ffado_wait_response 
     229ffado_streaming_wait(ffado_device_t *dev) { 
    229230    static int periods=0; 
    230231    static int periods_print=0; 
     
    242243    } 
    243244 
    244     if(dev->m_deviceManager->waitForPeriod()) { 
    245         return dev->options.period_size; 
     245    enum DeviceManager::eWaitResult result; 
     246    result = dev->m_deviceManager->waitForPeriod(); 
     247    if(result == DeviceManager::eWR_OK) { 
     248        return ffado_wait_ok; 
     249    } else if (result == DeviceManager::eWR_Xrun) { 
     250        debugWarning("Handled XRUN\n"); 
     251        xruns++; 
     252        return ffado_wait_xrun; 
    246253    } else { 
    247         debugWarning("XRUN\n"); 
     254        debugError("Unhandled XRUN (BUG)\n"); 
    248255        xruns++; 
    249         return -1
     256        return ffado_wait_error
    250257    } 
    251258} 
     
    261268int ffado_streaming_transfer_buffers(ffado_device_t *dev) { 
    262269    return dev->m_deviceManager->getStreamProcessorManager().transfer(); 
    263 } 
    264  
    265  
    266 int ffado_streaming_write(ffado_device_t *dev, int i, ffado_sample_t *buffer, int nsamples) { 
    267     Streaming::Port *p = dev->m_deviceManager->getStreamProcessorManager().getPortByIndex(i, Streaming::Port::E_Playback); 
    268     // use an assert here performancewise, 
    269     // it should already have failed before, if not correct 
    270     assert(p); 
    271  
    272     return p->writeEvents((void *)buffer, nsamples); 
    273 } 
    274  
    275 int ffado_streaming_read(ffado_device_t *dev, int i, ffado_sample_t *buffer, int nsamples) { 
    276     Streaming::Port *p=dev->m_deviceManager->getStreamProcessorManager().getPortByIndex(i, Streaming::Port::E_Capture); 
    277     // use an assert here performancewise, 
    278     // it should already have failed before, if not correct 
    279     assert(p); 
    280  
    281     return p->readEvents((void *)buffer, nsamples); 
    282270} 
    283271 
     
    354342} 
    355343 
    356 int ffado_streaming_set_stream_buffer_type(ffado_device_t *dev, int i, 
    357     ffado_streaming_buffer_type t, enum Streaming::Port::E_Direction direction) { 
    358  
    359     Streaming::Port *p = dev->m_deviceManager->getStreamProcessorManager().getPortByIndex(i, direction); 
    360     if(!p) { 
    361         debugWarning("Could not get %s port at index %d\n", 
    362             (direction==Streaming::Port::E_Playback?"Playback":"Capture"),i); 
    363         return -1; 
    364     } 
    365  
     344int ffado_streaming_set_audio_datatype(ffado_device_t *dev, 
     345    ffado_streaming_audio_datatype t) { 
    366346    switch(t) { 
    367     case ffado_buffer_type_int24: 
    368         if (!p->setDataType(Streaming::Port::E_Int24)) { 
    369             debugWarning("%s: Could not set data type to Int24\n",p->getName().c_str()); 
     347        case ffado_audio_datatype_int24: 
     348            if(!dev->m_deviceManager->getStreamProcessorManager().setAudioDataType( 
     349               Streaming::StreamProcessorManager::eADT_Int24)) { 
     350                debugError("Could not set datatype\n"); 
     351                return -1; 
     352            } 
     353            break; 
     354        case ffado_audio_datatype_float: 
     355            if(!dev->m_deviceManager->getStreamProcessorManager().setAudioDataType( 
     356               Streaming::StreamProcessorManager::eADT_Float)) { 
     357                debugError("Could not set datatype\n"); 
     358                return -1; 
     359            } 
     360            break; 
     361        default: 
     362            debugError("Invalid audio datatype\n"); 
    370363            return -1; 
    371         } 
    372         if (!p->setBufferType(Streaming::Port::E_PointerBuffer)) { 
    373             debugWarning("%s: Could not set buffer type to Pointerbuffer\n",p->getName().c_str()); 
    374             return -1; 
    375         } 
    376         break; 
    377     case ffado_buffer_type_float: 
    378         if (!p->setDataType(Streaming::Port::E_Float)) { 
    379             debugWarning("%s: Could not set data type to Float\n",p->getName().c_str()); 
    380             return -1; 
    381         } 
    382         if (!p->setBufferType(Streaming::Port::E_PointerBuffer)) { 
    383             debugWarning("%s: Could not set buffer type to Pointerbuffer\n",p->getName().c_str()); 
    384             return -1; 
    385         } 
    386         break; 
    387     case ffado_buffer_type_midi: 
    388         if (!p->setDataType(Streaming::Port::E_MidiEvent)) { 
    389             debugWarning("%s: Could not set data type to MidiEvent\n",p->getName().c_str()); 
    390             return -1; 
    391         } 
    392         if (!p->setBufferType(Streaming::Port::E_RingBuffer)) { 
    393             debugWarning("%s: Could not set buffer type to Ringbuffer\n",p->getName().c_str()); 
    394             return -1; 
    395         } 
    396         break; 
    397     default: 
    398         debugWarning("%s: Unsupported buffer type\n",p->getName().c_str()); 
    399         return -1; 
    400     } 
    401     return 0; 
    402  
    403 
    404  
    405 int ffado_streaming_set_playback_buffer_type(ffado_device_t *dev, int i, ffado_streaming_buffer_type t) { 
    406     return ffado_streaming_set_stream_buffer_type(dev, i, t, Streaming::Port::E_Playback); 
    407 
    408  
    409 int ffado_streaming_set_capture_buffer_type(ffado_device_t *dev, int i, ffado_streaming_buffer_type t) { 
    410     return ffado_streaming_set_stream_buffer_type(dev, i, t, Streaming::Port::E_Capture); 
     364    } 
     365    return 0; 
     366
     367 
     368ffado_streaming_audio_datatype ffado_streaming_get_audio_datatype(ffado_device_t *dev) { 
     369    switch(dev->m_deviceManager->getStreamProcessorManager().getAudioDataType()) { 
     370        case Streaming::StreamProcessorManager::eADT_Int24: 
     371            return ffado_audio_datatype_int24; 
     372        case Streaming::StreamProcessorManager::eADT_Float: 
     373            return ffado_audio_datatype_float; 
     374        default: 
     375            debugError("Invalid audio datatype\n"); 
     376            return ffado_audio_datatype_error; 
     377    } 
     378    #warning FIXME 
    411379} 
    412380 
     
    435403} 
    436404 
    437 // TODO: the way port buffers are set in the C api doesn't satisfy me 
    438405int ffado_streaming_set_capture_stream_buffer(ffado_device_t *dev, int i, char *buff) { 
    439         Streaming::Port *p = dev->m_deviceManager->getStreamProcessorManager().getPortByIndex(i, Streaming::Port::E_Capture); 
    440  
    441         // use an assert here performancewise, 
    442         // it should already have failed before, if not correct 
    443         assert(p); 
    444  
    445         p->useExternalBuffer(true); 
    446         p->setExternalBufferAddress((void *)buff); 
    447  
    448         return 0; 
    449  
     406    Streaming::Port *p = dev->m_deviceManager->getStreamProcessorManager().getPortByIndex(i, Streaming::Port::E_Capture); 
     407    // use an assert here performancewise, 
     408    // it should already have failed before, if not correct 
     409    assert(p); 
     410    p->setBufferAddress((void *)buff); 
     411    return 0; 
    450412} 
    451413 
    452414int ffado_streaming_set_playback_stream_buffer(ffado_device_t *dev, int i, char *buff) { 
    453         Streaming::Port *p = dev->m_deviceManager->getStreamProcessorManager().getPortByIndex(i, Streaming::Port::E_Playback); 
    454         // use an assert here performancewise, 
    455         // it should already have failed before, if not correct 
    456         assert(p); 
    457  
    458         p->useExternalBuffer(true); 
    459         p->setExternalBufferAddress((void *)buff); 
    460  
    461         return 0; 
    462 
     415    Streaming::Port *p = dev->m_deviceManager->getStreamProcessorManager().getPortByIndex(i, Streaming::Port::E_Playback); 
     416    // use an assert here performancewise, 
     417    // it should already have failed before, if not correct 
     418    assert(p); 
     419    p->setBufferAddress((void *)buff); 
     420    return 0; 
     421
  • trunk/libffado/src/genericavc/avc_avdevice.cpp

    r784 r833  
    443443    } 
    444444 
    445     if (!addPlugToProcessor(*outputPlug,p, 
     445    if (!addPlugToProcessor(*outputPlug, p, 
    446446        Streaming::Port::E_Capture)) { 
    447447        debugFatal("Could not add plug to processor!\n"); 
     
    472472 
    473473    if (snoopMode) { 
    474         if (!addPlugToProcessor(*inputPlug,p, 
     474        if (!addPlugToProcessor(*inputPlug, p, 
    475475            Streaming::Port::E_Capture)) { 
    476476            debugFatal("Could not add plug to processor!\n"); 
     
    478478        } 
    479479    } else { 
    480         if (!addPlugToProcessor(*inputPlug,p, 
     480        if (!addPlugToProcessor(*inputPlug, p, 
    481481            Streaming::Port::E_Playback)) { 
    482482            debugFatal("Could not add plug to processor!\n"); 
     
    532532                    channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location); 
    533533                p=new Streaming::AmdtpAudioPort( 
     534                        *processor, 
    534535                        portname.str(), 
    535536                        direction, 
     
    544545                    channelInfo->m_name.c_str(), channelInfo->m_streamPosition, processor->getPortCount(Streaming::Port::E_Midi)); 
    545546                p=new Streaming::AmdtpMidiPort( 
     547                        *processor, 
    546548                        portname.str(), 
    547549                        direction, 
     
    565567                    channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location); 
    566568                p=new Streaming::AmdtpAudioPort( 
     569                        *processor, 
    567570                        portname.str(), 
    568571                        direction, 
     
    581584            if (!p) { 
    582585                debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str()); 
    583             } else { 
    584  
    585                 if (!processor->addPort(p)) { 
    586                     debugWarning("Could not register port with stream processor\n"); 
    587                     return false; 
    588                 } 
    589586            } 
    590587         } 
  • trunk/libffado/src/libieee1394/IsoHandler.cpp

    r807 r833  
    174174IsoHandler::waitForClient() 
    175175{ 
    176     debugOutput(DEBUG_LEVEL_VERBOSE, "waiting...\n"); 
     176    //debugOutput(DEBUG_LEVEL_VERBOSE, "waiting...\n"); 
    177177    if(m_Client) { 
    178178        bool result = m_Client->waitForSignal(); 
    179         debugOutput(DEBUG_LEVEL_VERBOSE, " returns %d\n", result); 
     179        //debugOutput(DEBUG_LEVEL_VERBOSE, " returns %d\n", result); 
    180180        return result; 
    181181    } else { 
     
    188188IsoHandler::tryWaitForClient() 
    189189{ 
    190     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "waiting...\n"); 
     190    //debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "waiting...\n"); 
    191191    if(m_Client) { 
    192192        bool result = m_Client->tryWaitForSignal(); 
    193         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " returns %d\n", result); 
     193        //debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " returns %d\n", result); 
    194194        return result; 
    195195    } else { 
     
    214214    // wait for the availability of frames in the client 
    215215    // (blocking for transmit handlers) 
    216 #ifdef DEBUG 
     216#if 0 //#ifdef DEBUG 
    217217    if (getType() == eHT_Transmit) { 
    218         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) Waiting for Client to signal frame availability...\n", this); 
     218        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p) Waiting for Client to signal frame availability...\n", this); 
    219219    } 
    220220#endif 
     
    222222 
    223223#if ISOHANDLER_USE_POLL 
    224         uint64_t poll_enter = m_manager.get1394Service().getCurrentTimeAsUsecs(); 
    225         err = poll(&m_poll_fd, 1, m_poll_timeout); 
    226         uint64_t poll_exit = m_manager.get1394Service().getCurrentTimeAsUsecs(); 
    227         if (err == -1) { 
    228             if (errno == EINTR) { 
    229                 return true; 
    230             } 
    231             debugFatal("%p, poll error: %s\n", this, strerror (errno)); 
    232             return false; 
    233         } 
    234         uint64_t iter_enter=0; 
    235         uint64_t iter_exit=0; 
    236         if(m_poll_fd.revents & (POLLIN)) { 
    237             iter_enter = m_manager.get1394Service().getCurrentTimeAsUsecs(); 
    238             if(!iterate()) { 
    239                 debugOutput( DEBUG_LEVEL_VERBOSE, 
    240                             "IsoHandler (%p): Failed to iterate handler\n", 
    241                             this); 
     224        bool result = true; 
     225        while(result && m_Client && m_Client->canProcessPackets()) { 
     226            int err = poll(&m_poll_fd, 1, m_poll_timeout); 
     227            if (err == -1) { 
     228                if (errno == EINTR) { 
     229                    return true; 
     230                } 
     231                debugFatal("%p, poll error: %s\n", this, strerror (errno)); 
    242232                return false; 
    243233            } 
    244             iter_exit = m_manager.get1394Service().getCurrentTimeAsUsecs(); 
    245         } else { 
    246             if (m_poll_fd.revents & POLLERR) { 
    247                 debugWarning("error on fd for %p\n", this); 
     234 
     235            if(m_poll_fd.revents & (POLLIN)) { 
     236                result=iterate(); 
     237                if(!result) { 
     238                    debugOutput( DEBUG_LEVEL_VERBOSE, 
     239                                "IsoHandler (%p): Failed to iterate handler\n", 
     240                                this); 
     241                } 
     242            } else { 
     243                if (m_poll_fd.revents & POLLERR) { 
     244                    debugWarning("error on fd for %p\n", this); 
     245                } 
     246                if (m_poll_fd.revents & POLLHUP) { 
     247                    debugWarning("hangup on fd for %p\n",this); 
     248                } 
     249                break; 
    248250            } 
    249             if (m_poll_fd.revents & POLLHUP) { 
    250                 debugWarning("hangup on fd for %p\n",this); 
    251             } 
    252         } 
    253         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%c %p) poll took %lldus, iterate took %lldus\n",  
    254                     (getType()==eHT_Receive?'R':'X'), this,  
    255                     poll_exit-poll_enter, iter_exit-iter_enter); 
    256         return true; 
     251        } 
     252        return result; 
    257253#else 
    258         // iterate blocks if no 1394 data is available 
     254        // iterate() is blocking if no 1394 data is available 
    259255        // so poll'ing is not really necessary 
    260          
    261256        bool result = true; 
    262         while(result && m_Client->canProcessPackets()) { 
     257        while(result && m_Client && m_Client->canProcessPackets()) { 
    263258            result = iterate(); 
    264             debugOutput(DEBUG_LEVEL_VERBOSE, "(%p, %s) Iterate returned: %d\n", 
    265                         this, (m_type==eHT_Receive?"Receive":"Transmit"), result); 
     259//             if (getType() == eHT_Receive) { 
     260//                 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p, %s) Iterate returned: %d\n", 
     261//                             this, (m_type==eHT_Receive?"Receive":"Transmit"), result); 
     262//             } 
    266263        } 
    267264        return result; 
     
    275272bool 
    276273IsoHandler::iterate() { 
    277     debugOutput(DEBUG_LEVEL_VERBOSE, "(%p, %s) Iterating ISO handler\n",  
    278                 this, (m_type==eHT_Receive?"Receive":"Transmit")); 
     274//     if(m_type==eHT_Receive) { 
     275//         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p, %s) Iterating ISO handler\n",  
     276//                 this, (m_type==eHT_Receive?"Receive":"Transmit")); 
     277//     } 
    279278    if(m_State == E_Running) { 
    280279#if ISOHANDLER_FLUSH_BEFORE_ITERATE 
     
    282281#endif 
    283282        if(raw1394_loop_iterate(m_handle)) { 
    284             debugOutput( DEBUG_LEVEL_VERBOSE, 
    285                         "IsoHandler (%p): Failed to iterate handler: %s\n", 
     283            debugError( "IsoHandler (%p): Failed to iterate handler: %s\n", 
    286284                        this, strerror(errno)); 
    287285            return false; 
    288286        } 
     287//         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p, %s)  done iterating ISO handler\n",  
     288//                 this, (m_type==eHT_Receive?"Receive":"Transmit")); 
    289289        return true; 
    290290    } else { 
  • trunk/libffado/src/libieee1394/IsoHandlerManager.cpp

    r807 r833  
    378378        } 
    379379 
    380         max_packet_size = page_size; 
     380        //max_packet_size = page_size; // HACK 
    381381        unsigned int irq_interval = packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD; 
    382382        if(irq_interval <= 0) irq_interval=1; 
     
    395395            return false; 
    396396        } 
     397 
    397398    } else { 
    398399        debugFatal("Bad stream type\n"); 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpPort.h

    r742 r833  
    4747public: 
    4848 
    49     AmdtpAudioPort(std::string name, 
    50                        enum E_Direction direction, 
     49    AmdtpAudioPort(PortManager &m, 
     50                   std::string name, 
     51                   enum E_Direction direction, 
    5152                   int position, 
    5253                   int location, 
    5354                   enum E_Formats format) 
    54     : AudioPort(name, direction), 
     55    : AudioPort(m, name, direction), 
    5556      AmdtpPortInfo(position, location, format) 
    5657    {}; 
    5758 
    5859    virtual ~AmdtpAudioPort() {}; 
    59  
    60 protected: 
    61  
    6260}; 
    6361 
     
    7472public: 
    7573 
    76     AmdtpMidiPort(std::string name, 
    77                        enum E_Direction direction, 
    78                    int position, 
    79                    int location, 
    80                    enum E_Formats format) 
    81         : MidiPort(name, direction), 
     74    AmdtpMidiPort(PortManager &m, 
     75                  std::string name, 
     76                  enum E_Direction direction, 
     77                  int position, 
     78                  int location, 
     79                  enum E_Formats format) 
     80        : MidiPort(m, name, direction), 
    8281          AmdtpPortInfo(position, location, format) 
    8382    {}; 
    8483 
    85  
    8684    virtual ~AmdtpMidiPort() {}; 
    87  
    88 protected: 
    89  
    9085}; 
    9186 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpPortInfo.h

    r742 r833  
    6060 
    6161 
    62     int getLocation()     {return m_location;}; 
    63     int getPosition()     {return m_position;}; 
     62    unsigned int getLocation()     {return m_location;}; 
     63    unsigned int getPosition()     {return m_position;}; 
    6464    enum E_Formats getFormat()       {return m_format;}; 
    6565 
    6666protected: 
    67     int m_position; 
    68     int m_location; 
     67    unsigned int m_position; 
     68    unsigned int m_location; 
    6969    enum E_Formats m_format; 
    7070 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp

    r790 r833  
    167167 
    168168    if(m_data_buffer->writeFrames(nevents, (char *)(data+8), m_last_timestamp)) { 
    169         // process all ports that should be handled on a per-packet base 
    170         // this is MIDI for AMDTP (due to the need of DBC) 
    171         if(isRunning()) { 
    172             if (!decodePacketPorts((quadlet_t *)(data+8), nevents, packet->dbc)) { 
    173                 debugWarning("Problem decoding Packet Ports\n"); 
    174             } 
    175         } 
    176169        return eCRV_OK; 
    177170    } else { 
     
    193186    bool no_problem=true; 
    194187 
    195     for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    196           it != m_PeriodPorts.end(); 
     188    for ( PortVectorIterator it = m_Ports.begin(); 
     189          it != m_Ports.end(); 
    197190          ++it ) 
    198191    { 
     
    213206        case AmdtpPortInfo::E_SPDIF: // still unimplemented 
    214207            break; 
    215     /* for this processor, midi is a packet based port 
    216208        case AmdtpPortInfo::E_Midi: 
    217             break;*/ 
     209            if(decodeMidiEventsToPort(static_cast<AmdtpMidiPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
     210                debugWarning("Could not decode packet Midi to port %s",(*it)->getName().c_str()); 
     211                no_problem=false; 
     212            } 
     213            break; 
    218214        default: // ignore 
    219215            break; 
     
    223219} 
    224220 
    225 /** 
    226  * @brief decode a packet for the packet-based ports 
    227  * 
    228  * @param data Packet data 
    229  * @param nevents number of events in data (including events of other ports & port types) 
    230  * @param dbc DataBlockCount value for this packet 
    231  * @return true if all successfull 
    232  */ 
    233 bool AmdtpReceiveStreamProcessor::decodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc) 
    234 { 
    235     bool ok=true; 
    236  
    237     quadlet_t *target_event=NULL; 
    238     unsigned int j; 
    239  
    240     for ( PortVectorIterator it = m_PacketPorts.begin(); 
    241           it != m_PacketPorts.end(); 
    242           ++it ) 
    243     { 
    244  
    245 #ifdef DEBUG 
    246         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it); 
    247         assert(pinfo); // this should not fail!! 
    248  
    249         // the only packet type of events for AMDTP is MIDI in mbla 
    250         assert(pinfo->getFormat()==AmdtpPortInfo::E_Midi); 
    251 #endif 
    252         AmdtpMidiPort *mp=static_cast<AmdtpMidiPort *>(*it); 
    253  
    254         // we decode this directly (no function call) due to the high frequency 
    255         /* idea: 
    256         spec says: current_midi_port=(dbc+j)%8; 
    257         => if we start at (dbc+stream->location-1)%8, 
    258         we'll start at the right event for the midi port. 
    259         => if we increment j with 8, we stay at the right event. 
    260         */ 
    261         // FIXME: as we know in advance how big a packet is (syt_interval) we can 
    262         //        predict how much loops will be present here 
    263         for(j = (dbc & 0x07)+mp->getLocation(); j < nevents; j += 8) { 
    264             target_event=(quadlet_t *)(data + ((j * m_dimension) + mp->getPosition())); 
    265             quadlet_t sample_int=ntohl(*target_event); 
    266             // FIXME: this assumes that 2X and 3X speed isn't used, 
    267             // because only the 1X slot is put into the ringbuffer 
    268             if(IEC61883_AM824_GET_LABEL(sample_int) != IEC61883_AM824_LABEL_MIDI_NO_DATA) { 
    269                 sample_int=(sample_int >> 16) & 0x000000FF; 
    270                 if(!mp->writeEvent(&sample_int)) { 
    271                     debugWarning("Packet port events lost\n"); 
    272                     ok=false; 
    273                 } 
    274             } 
    275         } 
    276  
    277     } 
    278  
    279     return ok; 
    280 } 
    281  
    282221#if USE_SSE 
     222#error broken 
    283223typedef float v4sf __attribute__ ((vector_size (16))); 
    284224typedef int v4si __attribute__ ((vector_size (16))); 
     
    306246    switch(p->getDataType()) { 
    307247        default: 
     248            debugError("bad type: %d\n", p->getDataType()); 
     249            return -1; 
    308250        case Port::E_Int24: 
    309251            { 
     
    374316} 
    375317 
     318int 
     319AmdtpReceiveStreamProcessor::decodeMidiEventsToPort( 
     320                       AmdtpMidiPort *p, quadlet_t *data, 
     321                       unsigned int offset, unsigned int nevents) 
     322{ 
     323    #warning implement 
     324} 
     325 
    376326#else 
    377327 
     
    386336    target_event=(quadlet_t *)(data + p->getPosition()); 
    387337 
    388     switch(p->getDataType()) { 
     338    switch(m_StreamProcessorManager.getAudioDataType()) { 
    389339        default: 
    390         case Port::E_Int24: 
     340            debugError("bad type: %d\n", m_StreamProcessorManager.getAudioDataType()); 
     341            return -1; 
     342        case StreamProcessorManager::eADT_Int24: 
    391343            { 
    392344                quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress()); 
     
    403355            } 
    404356            break; 
    405         case Port::E_Float: 
     357        case StreamProcessorManager::eADT_Float: 
    406358            { 
    407359                const float multiplier = 1.0f / (float)(0x7FFFFF); 
     
    429381    return 0; 
    430382} 
     383 
     384int 
     385AmdtpReceiveStreamProcessor::decodeMidiEventsToPort( 
     386                       AmdtpMidiPort *p, quadlet_t *data, 
     387                       unsigned int offset, unsigned int nevents) 
     388{ 
     389    unsigned int j=0; 
     390    quadlet_t *target_event; 
     391    quadlet_t sample_int; 
     392    unsigned int position = p->getPosition(); 
     393    unsigned int location = p->getLocation(); 
     394 
     395    quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress()); 
     396 
     397    assert(nevents + offset <= p->getBufferSize()); 
     398 
     399    buffer+=offset; 
     400 
     401    // clear 
     402    memset(buffer, 0, nevents * 4); 
     403 
     404    // assumes that dbc%8 == 0, which is always true if data points to the 
     405    // start of a packet in blocking mode 
     406    // midi events that belong to the same time mpx-ed block should all be 
     407    // timed at the SYT timestamp of the packet. This basically means that they 
     408    // all correspond to the first audio frame in the packet. 
     409    for(j = location; j < nevents; j += 8) { 
     410        target_event=(quadlet_t *)(data + ((j * m_dimension) + position)); 
     411        sample_int=ntohl(*target_event); 
     412        // FIXME: this assumes that 2X and 3X speed isn't used, 
     413        // because only the 1X slot is put into the ringbuffer 
     414        if(IEC61883_AM824_GET_LABEL(sample_int) != IEC61883_AM824_LABEL_MIDI_NO_DATA) { 
     415            sample_int=(sample_int >> 16) & 0x000000FF; 
     416            sample_int |= 0x01000000; // flag that there is a midi event present 
     417            *buffer = sample_int; 
     418            debugOutput(DEBUG_LEVEL_VERBOSE, "Received midi byte %08X on port %p index %d\n", sample_int, p, j-location); 
     419        } 
     420        buffer += 8; // skip 8 frames 
     421    } 
     422 
     423    return 0; 
     424} 
     425 
    431426#endif 
    432427} // end of namespace Streaming 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.h

    r750 r833  
    101101 
    102102private: 
    103     bool decodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc); 
    104103    int decodeMBLAEventsToPort(AmdtpAudioPort *, quadlet_t *data, unsigned int offset, unsigned int nevents); 
     104    int decodeMidiEventsToPort(AmdtpMidiPort *p, quadlet_t *data, unsigned int offset, unsigned int nevents); 
    105105 
    106106    unsigned int getSytInterval(); 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp

    r798 r833  
    3737#include <assert.h> 
    3838 
     39#define AMDTP_FLOAT_MULTIPLIER 2147483392.0 
     40 
    3941namespace Streaming 
    4042{ 
     
    4547        , m_dimension( dimension ) 
    4648        , m_dbc( 0 ) 
     49        , m_nb_audio_ports( 0 ) 
     50        , m_nb_midi_ports( 0 ) 
    4751{} 
    4852 
     
    5357    int cycle, unsigned int dropped, unsigned int max_length ) 
    5458{ 
    55     struct iec61883_packet *packet = ( struct iec61883_packet * ) data; 
     59    __builtin_prefetch(data, 1, 0); // prefetch events for write, no temporal locality 
     60    struct iec61883_packet *packet = (struct iec61883_packet *)data; 
    5661    /* Our node ID can change after a bus reset, so it is best to fetch 
    5762    * our node ID for each packet. */ 
    58     packet->sid = m_1394service.getLocalNodeId() & 0x3f
     63    packet->sid = m_local_node_id
    5964 
    6065    packet->dbs = m_dimension; 
     
    249254    int cycle, unsigned int dropped, unsigned int max_length ) 
    250255{ 
    251     struct iec61883_packet *packet = ( struct iec61883_packet * ) data; 
    252256    if ( m_data_buffer->readFrames ( m_syt_interval, ( char * ) ( data + 8 ) ) ) 
    253257    { 
    254         // process all ports that should be handled on a per-packet base 
    255         // this is MIDI for AMDTP (due to the need of DBC) 
    256         if ( !encodePacketPorts ( ( quadlet_t * ) ( data+8 ), m_syt_interval, packet->dbc ) ) 
    257         { 
    258             debugWarning ( "Problem encoding Packet Ports\n" ); 
    259         } 
    260258        debugOutput ( DEBUG_LEVEL_ULTRA_VERBOSE, "XMIT DATA (cy %04d): TSP=%011llu (%04u)\n", 
    261259                    cycle, m_last_timestamp, ( unsigned int ) TICKS_TO_CYCLES ( m_last_timestamp ) ); 
     
    278276    /* Our node ID can change after a bus reset, so it is best to fetch 
    279277    * our node ID for each packet. */ 
    280     packet->sid = m_1394service.getLocalNodeId() & 0x3f
     278    packet->sid = m_local_node_id
    281279 
    282280    packet->dbs = m_dimension; 
     
    395393        m_syt_interval ); 
    396394 
    397     for ( PortVectorIterator it = m_Ports.begin(); 
    398             it != m_Ports.end(); 
    399             ++it ) 
    400     { 
    401         if ( ( *it )->getPortType() == Port::E_Midi ) 
    402         { 
    403             // we use a timing unit of 10ns 
    404             // this makes sure that for the max syt interval 
    405             // we don't have rounding, and keeps the numbers low 
    406             // we have 1 slot every 8 events 
    407             // we have syt_interval events per packet 
    408             // => syt_interval/8 slots per packet 
    409             // packet rate is 8000pkt/sec => interval=125us 
    410             // so the slot interval is (1/8000)/(syt_interval/8) 
    411             // or: 1/(1000 * syt_interval) sec 
    412             // which is 1e9/(1000*syt_interval) nsec 
    413             // or 100000/syt_interval 'units' 
    414             // the event interval is fixed to 320us = 32000 'units' 
    415             if ( ! ( *it )->useRateControl ( true, ( 100000/m_syt_interval ),32000, false ) ) 
    416             { 
    417                 debugFatal ( "Could not set signal type to PeriodSignalling" ); 
    418                 return false; 
    419             } 
    420             break; 
    421         } 
    422     } 
     395    if (!initPortCache()) { 
     396        debugError("Could not init port cache\n"); 
     397        return false; 
     398    } 
     399 
    423400    return true; 
    424401} 
     
    430407        unsigned int nevents, unsigned int offset ) 
    431408{ 
    432     bool no_problem = true; 
    433  
    434     for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    435           it != m_PeriodPorts.end(); 
    436           ++it ) 
     409    updatePortCache(); 
     410    switch(m_StreamProcessorManager.getAudioDataType()) { 
     411        case StreamProcessorManager::eADT_Int24: 
     412            encodeAudioPortsInt24((quadlet_t *)data, offset, nevents); 
     413            break; 
     414        case StreamProcessorManager::eADT_Float: 
     415            encodeAudioPortsFloat((quadlet_t *)data, offset, nevents); 
     416            break; 
     417    } 
     418    encodeMidiPorts((quadlet_t *)data, offset, nevents); 
     419    return true; 
     420
     421 
     422bool 
     423AmdtpTransmitStreamProcessor::transmitSilenceBlock( 
     424    char *data, unsigned int nevents, unsigned int offset) 
     425
     426    // no need to update the port cache when transmitting silence since 
     427    // no dynamic values are used to do so. 
     428 
     429    encodeAudioPortsSilence((quadlet_t *)data, offset, nevents); 
     430    encodeMidiPortsSilence((quadlet_t *)data, offset, nevents); 
     431    return true; 
     432
     433 
     434/** 
     435 * @brief encodes all audio ports in the cache to events (silent data) 
     436 * @param data  
     437 * @param offset  
     438 * @param nevents  
     439 */ 
     440void 
     441AmdtpTransmitStreamProcessor::encodeAudioPortsSilence(quadlet_t *data, 
     442                                                      unsigned int offset, 
     443                                                      unsigned int nevents) 
     444
     445    unsigned int j; 
     446    quadlet_t *target_event; 
     447    unsigned int i; 
     448 
     449    for (i = 0; i < m_nb_audio_ports; i++) { 
     450        target_event = (quadlet_t *)(data + i); 
     451        __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 
     452 
     453        for (j = 0;j < nevents; j += 1) 
     454        { 
     455            *target_event = htonl( 0x40000000 ); 
     456            target_event += m_dimension; 
     457            __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 
     458        } 
     459    } 
     460
     461 
     462/** 
     463 * @brief encodes all audio ports in the cache to events (float data) 
     464 * @param data  
     465 * @param offset  
     466 * @param nevents  
     467 */ 
     468void 
     469AmdtpTransmitStreamProcessor::encodeAudioPortsFloat(quadlet_t *data, 
     470                                                    unsigned int offset, 
     471                                                    unsigned int nevents) 
     472
     473    unsigned int j; 
     474    quadlet_t *target_event; 
     475    unsigned int i; 
     476 
     477    for (i = 0; i < m_nb_audio_ports; i++) { 
     478        struct _MBLA_port_cache &p = m_audio_ports.at(i); 
     479        target_event = (quadlet_t *)(data + i); 
     480        __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 
     481        assert(nevents + offset <= p.buffer_size ); 
     482 
     483        if(p.buffer && p.enabled) { 
     484            float *buffer = (float *)(p.buffer); 
     485            buffer += offset; 
     486            __builtin_prefetch(buffer, 0, 0); // prefetch events for read, no temporal locality 
     487     
     488            for (j = 0;j < nevents; j += 1) 
     489            { 
     490                // don't care for overflow 
     491                float v = (*buffer) * AMDTP_FLOAT_MULTIPLIER; 
     492                unsigned int tmp = ((int) v); 
     493                *target_event = htonl ( ( tmp >> 8 ) | 0x40000000 ); 
     494                buffer++; 
     495                __builtin_prefetch(buffer, 0, 0); // prefetch events for read, no temporal locality 
     496                target_event += m_dimension; 
     497                __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 
     498            } 
     499        } else { 
     500            for (j = 0;j < nevents; j += 1) 
     501            { 
     502                *target_event = htonl( 0x40000000 ); 
     503                target_event += m_dimension; 
     504                __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 
     505            } 
     506        } 
     507    } 
     508
     509 
     510/** 
     511 * @brief encodes all audio ports in the cache to events (int24 data) 
     512 * @param data  
     513 * @param offset  
     514 * @param nevents  
     515 */ 
     516void 
     517AmdtpTransmitStreamProcessor::encodeAudioPortsInt24(quadlet_t *data, 
     518                                                    unsigned int offset, 
     519                                                    unsigned int nevents) 
     520
     521    unsigned int j; 
     522    quadlet_t *target_event; 
     523    unsigned int i; 
     524 
     525    for (i = 0; i < m_nb_audio_ports; i++) { 
     526        struct _MBLA_port_cache &p = m_audio_ports.at(i); 
     527        target_event = (quadlet_t *)(data + i); 
     528        __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 
     529        assert(nevents + offset <= p.buffer_size ); 
     530 
     531        if(p.buffer && p.enabled) { 
     532            uint32_t *buffer = (uint32_t *)(p.buffer); 
     533            buffer += offset; 
     534            __builtin_prefetch(buffer, 0, 0); // prefetch events for read, no temporal locality 
     535 
     536            for (j = 0; j < nevents; j += 1) 
     537            { 
     538                *target_event = htonl(((*buffer) & 0x00FFFFFF) | 0x40000000); 
     539                buffer++; 
     540                __builtin_prefetch(buffer, 0, 0); // prefetch events for read, no temporal locality 
     541 
     542                target_event += m_dimension; 
     543                __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 
     544            } 
     545        } else { 
     546            for (j = 0;j < nevents; j += 1) 
     547            { 
     548                *target_event = htonl( 0x40000000 ); 
     549                target_event += m_dimension; 
     550                __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 
     551            } 
     552        } 
     553    } 
     554
     555 
     556/** 
     557 * @brief encodes all midi ports in the cache to events (silence) 
     558 * @param data  
     559 * @param offset  
     560 * @param nevents  
     561 */ 
     562void 
     563AmdtpTransmitStreamProcessor::encodeMidiPortsSilence(quadlet_t *data, 
     564                                                     unsigned int offset, 
     565                                                     unsigned int nevents) 
     566
     567    quadlet_t *target_event; 
     568    unsigned int i,j; 
     569 
     570    for (i = 0; i < m_nb_midi_ports; i++) { 
     571        struct _MIDI_port_cache &p = m_midi_ports.at(i); 
     572 
     573        for (j = p.location;j < nevents; j += 8) { 
     574            target_event = (quadlet_t *) (data + ((j * m_dimension) + p.position)); 
     575            __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 
     576            *target_event = htonl(IEC61883_AM824_SET_LABEL(0, IEC61883_AM824_LABEL_MIDI_NO_DATA)); 
     577        } 
     578    } 
     579
     580 
     581/** 
     582 * @brief encodes all midi ports in the cache to events 
     583 * @param data  
     584 * @param offset  
     585 * @param nevents  
     586 */ 
     587void 
     588AmdtpTransmitStreamProcessor::encodeMidiPorts(quadlet_t *data, 
     589                                              unsigned int offset, 
     590                                              unsigned int nevents) 
     591
     592    quadlet_t *target_event; 
     593    unsigned int i,j; 
     594 
     595    for (i = 0; i < m_nb_midi_ports; i++) { 
     596        struct _MIDI_port_cache &p = m_midi_ports.at(i); 
     597        if (p.buffer && p.enabled) { 
     598            uint32_t *buffer = (quadlet_t *)(p.buffer); 
     599            buffer += offset; 
     600            __builtin_prefetch(buffer, 0, 0); // prefetch events for read, no temporal locality 
     601     
     602            for (j = p.location;j < nevents; j += 8) { 
     603                target_event = (quadlet_t *) (data + ((j * m_dimension) + p.position)); 
     604                __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 
     605     
     606                if ( *buffer & 0xFF000000 )   // we can send a byte 
     607                { 
     608                    quadlet_t tmpval; 
     609                    tmpval = ((*buffer)<<16) & 0x00FF0000; 
     610                    tmpval = IEC61883_AM824_SET_LABEL(tmpval, IEC61883_AM824_LABEL_MIDI_1X); 
     611                    *target_event = htonl(tmpval); 
     612 
     613//                     debugOutput ( DEBUG_LEVEL_VERBOSE, "MIDI port %s, pos=%u, loc=%u, nevents=%u, dim=%d\n", 
     614//                                p.port->getName().c_str(), p.position, p.location, nevents, m_dimension ); 
     615//                     debugOutput ( DEBUG_LEVEL_VERBOSE, "base=%p, target=%p, value=%08X\n", 
     616//                                data, target_event, tmpval ); 
     617                } else { 
     618                    // can't send a byte, either because there is no byte, 
     619                    // or because this would exceed the maximum rate 
     620                    // FIXME: this can be ifdef optimized since it's a constant 
     621                    *target_event = htonl(IEC61883_AM824_SET_LABEL(0, IEC61883_AM824_LABEL_MIDI_NO_DATA)); 
     622                } 
     623                buffer+=8; 
     624            } 
     625        } else { 
     626            for (j = p.location;j < nevents; j += 8) { 
     627                target_event = (quadlet_t *) (data + ((j * m_dimension) + p.position)); 
     628                __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 
     629                *target_event = htonl(IEC61883_AM824_SET_LABEL(0, IEC61883_AM824_LABEL_MIDI_NO_DATA)); 
     630            } 
     631        } 
     632    } 
     633
     634 
     635bool 
     636AmdtpTransmitStreamProcessor::initPortCache() { 
     637    // make use of the fact that audio ports are the first ports in 
     638    // the cluster as per AMDTP. so we can sort the ports by position 
     639    // and have very efficient lookups: 
     640    // m_float_ports.at(i).buffer -> audio stream i buffer 
     641    // for midi ports we simply cache all port info since they are (usually) not 
     642    // that numerous 
     643    m_nb_audio_ports = 0; 
     644    m_audio_ports.clear(); 
     645     
     646    m_nb_midi_ports = 0; 
     647    m_midi_ports.clear(); 
     648     
     649    for(PortVectorIterator it = m_Ports.begin(); 
     650        it != m_Ports.end(); 
     651        ++it ) 
    437652    { 
    438         if ( (*it)->isDisabled() ) { continue; }; 
    439  
    440         //FIXME: make this into a static_cast when not DEBUG? 
    441         AmdtpPortInfo *pinfo = dynamic_cast<AmdtpPortInfo *> ( *it ); 
    442         assert ( pinfo ); // this should not fail!! 
     653        AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it); 
     654        assert(pinfo); // this should not fail!! 
    443655 
    444656        switch( pinfo->getFormat() ) 
    445657        { 
    446658            case AmdtpPortInfo::E_MBLA: 
    447                 if( encodePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents) ) 
    448                 { 
    449                     debugWarning ( "Could not encode port %s to MBLA events", (*it)->getName().c_str() ); 
    450                     no_problem = false; 
    451                 } 
     659                m_nb_audio_ports++; 
    452660                break; 
    453661            case AmdtpPortInfo::E_SPDIF: // still unimplemented 
    454662                break; 
    455             default: // ignore 
    456                 break; 
    457         } 
    458     } 
    459     return no_problem; 
    460 
    461  
    462 bool 
    463 AmdtpTransmitStreamProcessor::transmitSilenceBlock( 
    464     char *data, unsigned int nevents, unsigned int offset) 
    465 
    466     bool no_problem = true; 
    467     for(PortVectorIterator it = m_PeriodPorts.begin(); 
    468         it != m_PeriodPorts.end(); 
    469         ++it ) 
    470     { 
    471         //FIXME: make this into a static_cast when not DEBUG? 
    472         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it); 
    473         assert(pinfo); // this should not fail!! 
    474  
    475         switch( pinfo->getFormat() ) 
    476         { 
    477             case AmdtpPortInfo::E_MBLA: 
    478                 if ( encodeSilencePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents) ) 
    479                 { 
    480                     debugWarning("Could not encode port %s to MBLA events", (*it)->getName().c_str()); 
    481                     no_problem = false; 
    482                 } 
    483                 break; 
    484             case AmdtpPortInfo::E_SPDIF: // still unimplemented 
     663            case AmdtpPortInfo::E_Midi: 
     664                m_nb_midi_ports++; 
    485665                break; 
    486666            default: // ignore 
     
    488668        } 
    489669    } 
    490     return no_problem; 
    491 
    492  
    493 /** 
    494 * @brief decode a packet for the packet-based ports 
    495 
    496 * @param data Packet data 
    497 * @param nevents number of events in data (including events of other ports & port types) 
    498 * @param dbc DataBlockCount value for this packet 
    499 * @return true if all successfull 
    500 */ 
    501 bool AmdtpTransmitStreamProcessor::encodePacketPorts ( quadlet_t *data, unsigned int nevents, unsigned int dbc ) 
    502 
    503     bool ok=true; 
    504     quadlet_t byte; 
    505  
    506     quadlet_t *target_event=NULL; 
    507     unsigned int j; 
    508  
    509     for ( PortVectorIterator it = m_PacketPorts.begin(); 
    510             it != m_PacketPorts.end(); 
     670 
     671    unsigned int idx; 
     672    for (idx = 0; idx < m_nb_audio_ports; idx++) { 
     673        for(PortVectorIterator it = m_Ports.begin(); 
     674            it != m_Ports.end(); 
    511675            ++it ) 
     676        { 
     677            AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it); 
     678            debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "idx %u: looking at port %s at position %u\n", 
     679                                              idx, (*it)->getName().c_str(), pinfo->getPosition()); 
     680            if(pinfo->getPosition() == idx) { 
     681                struct _MBLA_port_cache p; 
     682                p.port = dynamic_cast<AmdtpAudioPort *>(*it); 
     683                if(p.port == NULL) { 
     684                    debugError("Port is not an AmdtpAudioPort!\n"); 
     685                    return false; 
     686                } 
     687                p.buffer = NULL; // to be filled by updatePortCache 
     688                #ifdef DEBUG 
     689                p.buffer_size = (*it)->getBufferSize(); 
     690                #endif 
     691 
     692                m_audio_ports.push_back(p); 
     693                debugOutput(DEBUG_LEVEL_VERBOSE, "Cached port %s at position %u\n", 
     694                                                 p.port->getName().c_str(), idx); 
     695                goto next_index; 
     696            } 
     697        } 
     698        debugError("No MBLA port found for position %d\n", idx); 
     699        return false; 
     700next_index: 
     701        continue; 
     702    } 
     703 
     704    for(PortVectorIterator it = m_Ports.begin(); 
     705        it != m_Ports.end(); 
     706        ++it ) 
    512707    { 
    513  
    514 #ifdef DEBUG 
    515         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *> ( *it ); 
    516         assert ( pinfo ); // this should not fail!! 
    517  
    518         // the only packet type of events for AMDTP is MIDI in mbla 
    519         assert ( pinfo->getFormat() ==AmdtpPortInfo::E_Midi ); 
    520 #endif 
    521  
    522         AmdtpMidiPort *mp=static_cast<AmdtpMidiPort *> ( *it ); 
    523  
    524         // we encode this directly (no function call) due to the high frequency 
    525         /* idea: 
    526         spec says: current_midi_port=(dbc+j)%8; 
    527         => if we start at (dbc+stream->location-1)%8, 
    528         we'll start at the right event for the midi port. 
    529         => if we increment j with 8, we stay at the right event. 
    530         */ 
    531         // FIXME: as we know in advance how big a packet is (syt_interval) we can 
    532         //        predict how much loops will be present here 
    533         // first prefill the buffer with NO_DATA's on all time muxed channels 
    534  
    535         for ( j = ( dbc & 0x07 ) +mp->getLocation(); j < nevents; j += 8 ) 
    536         { 
    537  
    538             quadlet_t tmpval; 
    539  
    540             target_event= ( quadlet_t * ) ( data + ( ( j * m_dimension ) + mp->getPosition() ) ); 
    541  
    542             if ( mp->canRead() )   // we can send a byte 
    543             { 
    544                 mp->readEvent ( &byte ); 
    545                 byte &= 0xFF; 
    546                 tmpval=htonl ( 
    547                         IEC61883_AM824_SET_LABEL ( ( byte ) <<16, 
    548                                                     IEC61883_AM824_LABEL_MIDI_1X ) ); 
    549  
    550                 debugOutput ( DEBUG_LEVEL_ULTRA_VERBOSE, "MIDI port %s, pos=%d, loc=%d, dbc=%d, nevents=%d, dim=%d\n", 
    551                             mp->getName().c_str(), mp->getPosition(), mp->getLocation(), dbc, nevents, m_dimension ); 
    552                 debugOutput ( DEBUG_LEVEL_ULTRA_VERBOSE, "base=%p, target=%p, value=%08X\n", 
    553                             data, target_event, tmpval ); 
    554  
    555             } 
    556             else 
    557             { 
    558                 // can't send a byte, either because there is no byte, 
    559                 // or because this would exceed the maximum rate 
    560                 tmpval=htonl ( 
    561                         IEC61883_AM824_SET_LABEL ( 0,IEC61883_AM824_LABEL_MIDI_NO_DATA ) ); 
    562             } 
    563  
    564             *target_event=tmpval; 
    565         } 
    566  
    567     } 
    568     return ok; 
    569 
    570  
    571 #if USE_SSE 
    572 typedef float v4sf __attribute__ ((vector_size (16))); 
    573 typedef int v4si __attribute__ ((vector_size (16))); 
    574 typedef int v2si __attribute__ ((vector_size (8))); 
    575  
    576 int AmdtpTransmitStreamProcessor::encodePortToMBLAEvents ( AmdtpAudioPort *p, quadlet_t *data, 
    577         unsigned int offset, unsigned int nevents ) 
    578 
    579     static const float sse_multiplier[4] __attribute__((aligned(16))) = { 
    580         (float)(0x7FFFFF00), 
    581         (float)(0x7FFFFF00), 
    582         (float)(0x7FFFFF00), 
    583         (float)(0x7FFFFF00) 
    584     }; 
    585  
    586     static const int sse_mask[4] __attribute__((aligned(16))) = { 
    587         0x40000000,  0x40000000,  0x40000000,  0x40000000 
    588     }; 
    589  
    590     unsigned int out[4]; 
    591  
    592     unsigned int j=0; 
    593     unsigned int read=0; 
    594  
    595     quadlet_t *target_event; 
    596  
    597     target_event= ( quadlet_t * ) ( data + p->getPosition() ); 
    598  
    599     switch ( p->getDataType() ) 
    600     { 
    601         default: 
    602         case Port::E_Int24: 
    603         { 
    604             quadlet_t *buffer= ( quadlet_t * ) ( p->getBufferAddress() ); 
    605  
    606             assert ( nevents + offset <= p->getBufferSize() ); 
    607  
    608             buffer+=offset; 
    609  
    610             for ( j = 0; j < nevents; j += 1 )   // decode max nsamples 
    611             { 
    612                 *target_event = htonl ( ( * ( buffer ) & 0x00FFFFFF ) | 0x40000000 ); 
    613                 buffer++; 
    614                 target_event += m_dimension; 
    615             } 
    616         } 
    617         break; 
    618         case Port::E_Float: 
    619         { 
    620             const float multiplier = ( float ) ( 0x7FFFFF00 ); 
    621             float *buffer= ( float * ) ( p->getBufferAddress() ); 
    622  
    623             assert ( nevents + offset <= p->getBufferSize() ); 
    624  
    625             buffer+=offset; 
    626  
    627             j=0; 
    628             if(read>3) { 
    629                 for (j = 0; j < read-3; j += 4) { 
    630                     asm("movups %[floatbuff], %%xmm0\n\t" 
    631                             "mulps %[ssemult], %%xmm0\n\t" 
    632                             "cvttps2pi %%xmm0, %[out1]\n\t" 
    633                             "movhlps %%xmm0, %%xmm0\n\t" 
    634                             "psrld $8, %[out1]\n\t" 
    635                             "cvttps2pi %%xmm0, %[out2]\n\t" 
    636                             "por %[mmxmask], %[out1]\n\t" 
    637                             "psrld $8, %[out2]\n\t" 
    638                             "por %[mmxmask], %[out2]\n\t" 
    639                         : [out1] "=&y" (*(v2si*)&out[0]), 
    640                     [out2] "=&y" (*(v2si*)&out[2]) 
    641                         : [floatbuff] "m" (*(v4sf*)buffer), 
    642                     [ssemult] "x" (*(v4sf*)sse_multiplier), 
    643                     [mmxmask] "y" (*(v2si*)sse_mask) 
    644                         : "xmm0"); 
    645                     buffer += 4; 
    646                     *target_event = htonl(out[0]); 
    647                     target_event += m_dimension; 
    648                     *target_event = htonl(out[1]); 
    649                     target_event += m_dimension; 
    650                     *target_event = htonl(out[2]); 
    651                     target_event += m_dimension; 
    652                     *target_event = htonl(out[3]); 
    653                     target_event += m_dimension; 
    654                 } 
    655             } 
    656             for(; j < read; ++j) { 
    657             // don't care for overflow 
    658                 float v = *buffer * multiplier;  // v: -231 .. 231 
    659                 unsigned int tmp = (int)v; 
    660                 *target_event = htonl((tmp >> 8) | 0x40000000); 
    661      
    662                 buffer++; 
    663                 target_event += m_dimension; 
    664             } 
    665  
    666             asm volatile("emms"); 
    667             break; 
    668         } 
    669         break; 
    670     } 
    671  
    672     return 0; 
    673 
    674  
    675 #else 
    676  
    677 int AmdtpTransmitStreamProcessor::encodePortToMBLAEvents ( AmdtpAudioPort *p, quadlet_t *data, 
    678         unsigned int offset, unsigned int nevents ) 
    679 
    680     unsigned int j=0; 
    681  
    682     quadlet_t *target_event; 
    683  
    684     target_event= ( quadlet_t * ) ( data + p->getPosition() ); 
    685  
    686     switch ( p->getDataType() ) 
    687     { 
    688         default: 
    689         case Port::E_Int24: 
    690         { 
    691             quadlet_t *buffer= ( quadlet_t * ) ( p->getBufferAddress() ); 
    692  
    693             assert ( nevents + offset <= p->getBufferSize() ); 
    694  
    695             buffer+=offset; 
    696  
    697             for ( j = 0; j < nevents; j += 1 )   // decode max nsamples 
    698             { 
    699                 *target_event = htonl ( ( * ( buffer ) & 0x00FFFFFF ) | 0x40000000 ); 
    700                 buffer++; 
    701                 target_event += m_dimension; 
    702             } 
    703         } 
    704         break; 
    705         case Port::E_Float: 
    706         { 
    707             const float multiplier = ( float ) ( 0x7FFFFF00 ); 
    708             float *buffer= ( float * ) ( p->getBufferAddress() ); 
    709  
    710             assert ( nevents + offset <= p->getBufferSize() ); 
    711  
    712             buffer+=offset; 
    713  
    714             for ( j = 0; j < nevents; j += 1 )   // decode max nsamples 
    715             { 
    716  
    717                 // don't care for overflow 
    718                 float v = *buffer * multiplier;  // v: -231 .. 231 
    719                 unsigned int tmp = ( ( int ) v ); 
    720                 *target_event = htonl ( ( tmp >> 8 ) | 0x40000000 ); 
    721  
    722                 buffer++; 
    723                 target_event += m_dimension; 
    724             } 
    725         } 
    726         break; 
    727     } 
    728  
    729     return 0; 
    730 
    731 #endif 
    732  
    733 int AmdtpTransmitStreamProcessor::encodeSilencePortToMBLAEvents ( AmdtpAudioPort *p, quadlet_t *data, 
    734         unsigned int offset, unsigned int nevents ) 
    735 
    736     unsigned int j=0; 
    737  
    738     quadlet_t *target_event; 
    739  
    740     target_event= ( quadlet_t * ) ( data + p->getPosition() ); 
    741  
    742     switch ( p->getDataType() ) 
    743     { 
    744         default: 
    745         case Port::E_Int24: 
    746         case Port::E_Float: 
    747         { 
    748             for ( j = 0; j < nevents; j += 1 )   // decode max nsamples 
    749             { 
    750                 *target_event = htonl ( 0x40000000 ); 
    751                 target_event += m_dimension; 
    752             } 
    753         } 
    754         break; 
    755     } 
    756  
    757     return 0; 
     708        AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it); 
     709        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "idx %u: looking at port %s at position %u, location %u\n", 
     710                                        idx, (*it)->getName().c_str(), pinfo->getPosition(), pinfo->getLocation()); 
     711        if ((*it)->getPortType() == Port::E_Midi) { 
     712            struct _MIDI_port_cache p; 
     713            p.port = dynamic_cast<AmdtpMidiPort *>(*it); 
     714            if(p.port == NULL) { 
     715                debugError("Port is not an AmdtpMidiPort!\n"); 
     716                return false; 
     717            } 
     718            p.position = pinfo->getPosition(); 
     719            p.location = pinfo->getLocation(); 
     720            p.buffer = NULL; // to be filled by updatePortCache 
     721            #ifdef DEBUG 
     722            p.buffer_size = (*it)->getBufferSize(); 
     723            #endif 
     724 
     725            m_midi_ports.push_back(p); 
     726            debugOutput(DEBUG_LEVEL_VERBOSE, "Cached port %s at position %u, location %u\n", 
     727                                            p.port->getName().c_str(), p.position, p.location); 
     728        } 
     729    } 
     730 
     731    return true; 
     732
     733 
     734void 
     735AmdtpTransmitStreamProcessor::updatePortCache() { 
     736    unsigned int idx; 
     737    for (idx = 0; idx < m_nb_audio_ports; idx++) { 
     738        struct _MBLA_port_cache& p = m_audio_ports.at(idx); 
     739        AmdtpAudioPort *port = p.port; 
     740        p.buffer = port->getBufferAddress(); 
     741        p.enabled = !port->isDisabled(); 
     742    } 
     743    for (idx = 0; idx < m_nb_midi_ports; idx++) { 
     744        struct _MIDI_port_cache& p = m_midi_ports.at(idx); 
     745        AmdtpMidiPort *port = p.port; 
     746        p.buffer = port->getBufferAddress(); 
     747        p.enabled = !port->isDisabled(); 
     748    } 
    758749} 
    759750 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h

    r750 r833  
    115115                        unsigned int offset); 
    116116 
    117     bool encodePacketPorts(quadlet_t *data, unsigned int nevents, 
    118                            unsigned int dbc); 
    119  
    120     int encodePortToMBLAEvents(AmdtpAudioPort *, quadlet_t *data, 
    121                                 unsigned int offset, unsigned int nevents); 
    122     int encodeSilencePortToMBLAEvents(AmdtpAudioPort *, quadlet_t *data, 
    123                                 unsigned int offset, unsigned int nevents); 
     117    void encodeAudioPortsSilence(quadlet_t *data, unsigned int offset, unsigned int nevents); 
     118    void encodeAudioPortsFloat(quadlet_t *data, unsigned int offset, unsigned int nevents); 
     119    void encodeAudioPortsInt24(quadlet_t *data, unsigned int offset, unsigned int nevents); 
     120    void encodeMidiPortsSilence(quadlet_t *data, unsigned int offset, unsigned int nevents); 
     121    void encodeMidiPorts(quadlet_t *data, unsigned int offset, unsigned int nevents); 
    124122 
    125123    unsigned int getFDF(); 
     
    131129    int m_fdf; 
    132130    unsigned int m_dbc; 
     131 
     132private: // local port caching for performance 
     133    struct _MBLA_port_cache { 
     134        AmdtpAudioPort*     port; 
     135        void*               buffer; 
     136        bool                enabled; 
     137#ifdef DEBUG 
     138        unsigned int        buffer_size; 
     139#endif 
     140    }; 
     141    std::vector<struct _MBLA_port_cache> m_audio_ports; 
     142    unsigned int m_nb_audio_ports; 
     143 
     144    struct _MIDI_port_cache { 
     145        AmdtpMidiPort*      port; 
     146        void*               buffer; 
     147        bool                enabled; 
     148        unsigned int        position; 
     149        unsigned int        location; 
     150#ifdef DEBUG 
     151        unsigned int        buffer_size; 
     152#endif 
     153    }; 
     154    std::vector<struct _MIDI_port_cache> m_midi_ports; 
     155    unsigned int m_nb_midi_ports; 
     156 
     157    bool initPortCache(); 
     158    void updatePortCache(); 
    133159}; 
    134160 
  • trunk/libffado/src/libstreaming/generic/Port.cpp

    r750 r833  
    2323 
    2424#include "Port.h" 
     25#include "PortManager.h" 
    2526 
    2627#include <stdlib.h> 
     
    3132IMPL_DEBUG_MODULE( Port, Port, DEBUG_LEVEL_NORMAL ); 
    3233 
    33 Port::Port(std::string name, enum E_PortType porttype, enum E_Direction direction) 
    34       : m_Name(name), 
    35     m_SignalType(E_PeriodSignalled), 
    36     m_BufferType(E_PointerBuffer), 
    37     m_disabled(true), 
    38     m_buffersize(0), 
    39     m_eventsize(0), 
    40     m_DataType(E_Int24), 
    41     m_PortType(porttype), 
    42     m_Direction(direction), 
    43     m_buffer(0), 
    44     m_ringbuffer(0), 
    45     m_use_external_buffer(false), 
    46     m_do_ratecontrol(false), 
    47     m_event_interval(0), 
    48     m_slot_interval(0), 
    49     m_rate_counter(0), 
    50     m_rate_counter_minimum(0), 
    51     m_average_ratecontrol(false), 
    52     m_State(E_Created) 
     34Port::Port(PortManager& m, std::string name,  
     35           enum E_PortType porttype, enum E_Direction direction) 
     36    : m_Name( name ) 
     37    , m_disabled( true ) 
     38    , m_buffersize( 0 ) 
     39    , m_PortType( porttype ) 
     40    , m_Direction( direction ) 
     41    , m_buffer( NULL ) 
     42    , m_manager( m ) 
     43    , m_State( E_Created ) 
    5344{ 
     45    m_manager.registerPort(this); 
     46} 
    5447 
     48Port::~Port() { 
     49    debugOutput( DEBUG_LEVEL_VERBOSE, "deleting port %s\n", getName().c_str()); 
     50    m_manager.unregisterPort(this); 
    5551} 
    5652 
     
    6965    } 
    7066 
    71     if (m_buffersize==0) { 
     67    if (m_buffersize == 0) { 
    7268        debugFatal("Cannot initialize a port with buffersize=0\n"); 
    7369        return false; 
    7470    } 
    7571 
    76     switch (m_BufferType) { 
    77         case E_PointerBuffer: 
    78             if (m_use_external_buffer) { 
    79                 // don't do anything 
    80             } else if (!allocateInternalBuffer()) { 
    81                 debugFatal("Could not allocate internal buffer!\n"); 
    82                 return false; 
    83             } 
    84             break; 
    85  
    86         case E_RingBuffer: 
    87             if (m_use_external_buffer) { 
    88                 debugFatal("Cannot use an external ringbuffer! \n"); 
    89                 return false; 
    90             } else if (!allocateInternalRingBuffer()) { 
    91                 debugFatal("Could not allocate internal ringbuffer!\n"); 
    92                 return false; 
    93             } 
    94             break; 
    95         default: 
    96             debugFatal("Unsupported buffer type! (%d)\n",(int)m_BufferType); 
    97             return false; 
    98             break; 
    99     } 
    100  
    101     m_eventsize=getEventSize(); // this won't change, so cache it 
    102      
    10372    m_State = E_Initialized; 
    10473    return true; 
     
    10675 
    10776bool Port::reset() { 
    108     if (m_BufferType==E_RingBuffer) { 
    109         ffado_ringbuffer_reset(m_ringbuffer); 
    110     } 
    11177    return true; 
    112 }; 
     78} 
    11379 
    11480bool Port::setName(std::string name) { 
     
    134100 
    135101unsigned int Port::getEventSize() { 
    136     switch (m_DataType) { 
    137         case E_Float: 
    138             return sizeof(float); 
    139         case E_Int24: // 24 bit 2's complement, packed in a 32bit integer (LSB's) 
    140             return sizeof(uint32_t); 
    141         case E_MidiEvent: 
    142             return sizeof(uint32_t); 
    143         default: 
    144             return 0; 
    145     } 
    146 
    147  
    148 bool Port::setDataType(enum E_DataType d) { 
    149     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting datatype to %d for port %s\n",(int) d,m_Name.c_str()); 
    150     if (m_State != E_Created) { 
    151         debugFatal("Port (%s) not in E_Created state: %d\n",m_Name.c_str(),m_State); 
    152         return false; 
    153     } 
    154  
    155     // do some sanity checks 
    156     bool type_is_ok=false; 
    157     switch (m_PortType) { 
    158         case E_Audio: 
    159             if(d == E_Int24) type_is_ok=true; 
    160             if(d == E_Float) type_is_ok=true; 
    161             break; 
    162         case E_Midi: 
    163             if(d == E_MidiEvent) type_is_ok=true; 
    164             break; 
    165         case E_Control: 
    166             if(d == E_Default) type_is_ok=true; 
    167             break; 
    168         default: 
    169             break; 
    170     } 
    171  
    172     if(!type_is_ok) { 
    173         debugFatal("Datatype not supported by this type of port!\n"); 
    174         return false; 
    175     } 
    176  
    177     m_DataType=d; 
    178     return true; 
    179 
    180  
    181 bool Port::setSignalType(enum E_SignalType s) { 
    182     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting signaltype to %d for port %s\n",(int)s,m_Name.c_str()); 
    183     if (m_State != E_Created) { 
    184         debugFatal("Port (%s) not in E_Created state: %d\n",m_Name.c_str(),m_State); 
    185         return false; 
    186     } 
    187  
    188     // do some sanity checks 
    189     bool type_is_ok=false; 
    190     switch (m_PortType) { 
    191         case E_Audio: 
    192             if(s == E_PeriodSignalled) type_is_ok=true; 
    193             break; 
    194         case E_Midi: 
    195             if(s == E_PacketSignalled) type_is_ok=true; 
    196             break; 
    197         case E_Control: 
    198             if(s == E_PeriodSignalled) type_is_ok=true; 
    199             break; 
    200         default: 
    201             break; 
    202     } 
    203     if(!type_is_ok) { 
    204         debugFatal("Signalling type not supported by this type of port!\n"); 
    205         return false; 
    206     } 
    207     m_SignalType=s; 
    208     return true; 
    209 
    210  
    211 bool Port::setBufferType(enum E_BufferType b) { 
    212     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting buffer type to %d for port %s\n",(int)b,m_Name.c_str()); 
    213     if (m_State != E_Created) { 
    214         debugFatal("Port (%s) not in E_Created state: %d\n",m_Name.c_str(),m_State); 
    215         return false; 
    216     } 
    217     // do some sanity checks 
    218     bool type_is_ok=false; 
    219     switch (m_PortType) { 
    220         case E_Audio: 
    221             if(b == E_PointerBuffer) type_is_ok=true; 
    222             break; 
    223         case E_Midi: 
    224             if(b == E_RingBuffer) type_is_ok=true; 
    225             break; 
    226         case E_Control: 
    227             break; 
    228         default: 
    229             break; 
    230     } 
    231     if(!type_is_ok) { 
    232         debugFatal("Buffer type not supported by this type of port!\n"); 
    233         return false; 
    234     } 
    235     m_BufferType=b; 
    236     return true; 
    237 
    238  
    239 bool Port::useExternalBuffer(bool b) { 
    240     // If called on an initialised stream but the request isn't for a change silently 
    241     // allow it (relied on by C API as used by jack backend driver) 
    242     if (m_State==E_Initialized && m_use_external_buffer==b) 
    243         return true; 
    244  
    245     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting external buffer use to %d for port %s\n",(int)b,m_Name.c_str()); 
    246  
    247     if (m_State != E_Created) { 
    248         debugFatal("Port (%s) not in E_Created state: %d\n",m_Name.c_str(),m_State); 
    249         return false; 
    250     } 
    251     m_use_external_buffer=b; 
    252     return true; 
     102    return 4; // whether it's float, int24, midi or control, it's 4 
    253103} 
    254104 
    255105// buffer handling api's for pointer buffers 
    256106/** 
    257  * Get the buffer address (being the external or the internal one). 
     107 * Get the buffer address 
    258108 * 
    259109 * @param buff 
    260110 */ 
    261111void *Port::getBufferAddress() { 
    262     assert(m_BufferType==E_PointerBuffer); 
    263112    return m_buffer; 
    264113}; 
     
    266115/** 
    267116 * Set the external buffer address. 
    268  * only call this when you have specified that you will use 
    269  * an external buffer before doing the init() 
    270117 * 
    271118 * @param buff 
    272119 */ 
    273 void Port::setExternalBufferAddress(void *buff) { 
    274     assert(m_BufferType==E_PointerBuffer); 
    275     assert(m_use_external_buffer); // don't call this with an internal buffer! 
     120void Port::setBufferAddress(void *buff) { 
    276121    m_buffer=buff; 
    277 }; 
    278  
    279 // buffer handling api's for ringbuffers 
    280 bool Port::writeEvent(void *event) { 
    281  
    282 #ifdef DEBUG 
    283     if (m_State != E_Initialized) { 
    284         debugFatal("Port (%s) not in E_Initialized state: %d\n",m_Name.c_str(),m_State); 
    285         return false; 
    286     } 
    287      
    288     if(m_BufferType!=E_RingBuffer) { 
    289         debugError("operation not allowed on non E_RingBuffer ports\n"); 
    290         show(); 
    291         return false; 
    292     } 
    293     assert(m_ringbuffer); 
    294 #endif 
    295  
    296     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Writing event %08X with size %d to port %s\n",*((quadlet_t *)event),m_eventsize, m_Name.c_str()); 
    297  
    298     return (ffado_ringbuffer_write(m_ringbuffer, (char *)event, m_eventsize)==m_eventsize); 
    299 } 
    300  
    301 bool Port::readEvent(void *event) { 
    302  
    303 #ifdef DEBUG 
    304     if (m_State != E_Initialized) { 
    305         debugFatal("Port (%s) not in E_Initialized state: %d\n",m_Name.c_str(),m_State); 
    306         return false; 
    307     } 
    308      
    309     if(m_BufferType!=E_RingBuffer) { 
    310         debugError("operation not allowed on non E_RingBuffer ports\n"); 
    311         show(); 
    312         return false; 
    313     } 
    314     assert(m_ringbuffer); 
    315 #endif 
    316  
    317      
    318     unsigned int read=ffado_ringbuffer_read(m_ringbuffer, (char *)event, m_eventsize); 
    319      
    320     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Reading event %X with size %d from port %s\n",*((quadlet_t *)event),m_eventsize,m_Name.c_str()); 
    321  
    322  
    323     return (read==m_eventsize); 
    324 } 
    325  
    326 int Port::writeEvents(void *event, unsigned int nevents) { 
    327  
    328 #ifdef DEBUG 
    329     if (m_State != E_Initialized) { 
    330         debugFatal("Port (%s) not in E_Initialized state: %d\n",m_Name.c_str(),m_State); 
    331         return false; 
    332     } 
    333      
    334     if(m_BufferType!=E_RingBuffer) { 
    335         debugError("operation not allowed on non E_RingBuffer ports\n"); 
    336         show(); 
    337         return false; 
    338     } 
    339     assert(m_ringbuffer); 
    340 #endif 
    341  
    342  
    343     unsigned int bytes2write=m_eventsize*nevents; 
    344  
    345     unsigned int written=ffado_ringbuffer_write(m_ringbuffer, (char *)event,bytes2write)/m_eventsize; 
    346  
    347 #ifdef DEBUG 
    348     if(written) { 
    349         unsigned int i=0; 
    350         quadlet_t * tmp=(quadlet_t *)event; 
    351         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Written %d events (",written); 
    352         for (i=0;i<written;i++) { 
    353             debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "%X ", *(tmp+i)); 
    354         } 
    355         debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, ") to port %s\n",m_Name.c_str()); 
    356     } 
    357 #endif 
    358  
    359     return written; 
    360  
    361 } 
    362  
    363 int Port::readEvents(void *event, unsigned int nevents) { 
    364  
    365 #ifdef DEBUG 
    366     if (m_State != E_Initialized) { 
    367         debugFatal("Port (%s) not in E_Initialized state: %d\n",m_Name.c_str(),m_State); 
    368         return false; 
    369     } 
    370     if(m_BufferType!=E_RingBuffer) { 
    371         debugError("operation not allowed on non E_RingBuffer ports\n"); 
    372         show(); 
    373         return false; 
    374     } 
    375     assert(m_ringbuffer); 
    376 #endif 
    377  
    378  
    379     unsigned int bytes2read=m_eventsize*nevents; 
    380  
    381     unsigned int read=ffado_ringbuffer_read(m_ringbuffer, (char *)event, bytes2read)/m_eventsize; 
    382  
    383 #ifdef DEBUG 
    384     if(read) { 
    385         unsigned int i=0; 
    386         quadlet_t * tmp=(quadlet_t *)event; 
    387         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Read %d events (",read); 
    388         for (i=0;i<read;i++) { 
    389             debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "%X ", *(tmp+i)); 
    390         } 
    391         debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, ") from port %s\n",m_Name.c_str()); 
    392     } 
    393 #endif 
    394  
    395     return read; 
    396 } 
    397  
    398 /* rate control */ 
    399 bool Port::canRead() { 
    400     bool byte_present_in_buffer; 
    401  
    402     bool retval=false; 
    403  
    404     assert(m_ringbuffer); 
    405  
    406     byte_present_in_buffer=(ffado_ringbuffer_read_space(m_ringbuffer) >= m_eventsize); 
    407  
    408     if(byte_present_in_buffer) { 
    409  
    410         if(!m_do_ratecontrol) { 
    411             return true; 
    412         } 
    413  
    414         if(m_rate_counter <= 0) { 
    415             // update the counter 
    416             if(m_average_ratecontrol) { 
    417                 m_rate_counter += m_event_interval; 
    418                 assert(m_rate_counter<m_event_interval); 
    419             } else { 
    420                 m_rate_counter = m_event_interval; 
    421             } 
    422  
    423             retval=true; 
    424         } else { 
    425             debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Rate limit (%s)! rate_counter=%d \n",m_Name.c_str(),m_rate_counter); 
    426  
    427         } 
    428     } 
    429  
    430  
    431     m_rate_counter -= m_slot_interval; 
    432  
    433     // we have to limit the decrement of the ratecounter somehow. 
    434     // m_rate_counter_minimum is initialized when enabling ratecontrol 
    435     if(m_rate_counter < m_rate_counter_minimum) { 
    436         m_rate_counter = m_rate_counter_minimum; 
    437     } 
    438  
    439     return retval; 
    440 } 
    441  
    442 bool Port::useRateControl(bool use, unsigned int slot_interval, 
    443                                 unsigned int event_interval, bool average) { 
    444  
    445     if (use) { 
    446         debugOutput(DEBUG_LEVEL_VERBOSE, "Enabling rate control for port %s...\n",m_Name.c_str()); 
    447         if(slot_interval>event_interval) { 
    448             debugWarning("Rate control not needed!\n",m_Name.c_str()); 
    449             m_do_ratecontrol=false; 
    450             return false; 
    451         } 
    452         if(slot_interval==0) { 
    453             debugFatal("Cannot have slot interval == 0!\n"); 
    454             m_do_ratecontrol=false; 
    455             return false; 
    456         } 
    457         if(event_interval==0) { 
    458             debugFatal("Cannot have event interval == 0!\n"); 
    459             m_do_ratecontrol=false; 
    460             return false; 
    461         } 
    462         m_do_ratecontrol=use; 
    463         m_event_interval=event_interval; 
    464         m_slot_interval=slot_interval; 
    465         m_rate_counter=0; 
    466  
    467         // NOTE: pretty arbitrary, but in average mode this limits the peak stream rate 
    468         m_rate_counter_minimum=-(2*event_interval); 
    469  
    470         m_average_ratecontrol=average; 
    471  
    472     } else { 
    473         debugOutput(DEBUG_LEVEL_VERBOSE, "Disabling rate control for port %s...\n",m_Name.c_str()); 
    474         m_do_ratecontrol=use; 
    475     } 
    476     return true; 
    477122} 
    478123 
     
    482127    debugOutput(DEBUG_LEVEL_VERBOSE, "Enabling port %s...\n",m_Name.c_str()); 
    483128    m_disabled=false; 
    484 }; 
     129} 
    485130 
    486131/// Disable the port. (this can be called anytime) 
     
    489134    debugOutput(DEBUG_LEVEL_VERBOSE, "Disabling port %s...\n",m_Name.c_str()); 
    490135    m_disabled=false; 
    491 }; 
    492  
    493  
    494 /* Private functions */ 
    495  
    496 bool Port::allocateInternalBuffer() { 
    497     int event_size=getEventSize(); 
    498  
    499     debugOutput(DEBUG_LEVEL_VERBOSE, 
    500                 "Allocating internal buffer of %d events with size %d (%s)\n", 
    501                 m_buffersize, event_size, m_Name.c_str()); 
    502  
    503     if(m_buffer) { 
    504         debugWarning("already has an internal buffer attached, re-allocating\n"); 
    505         freeInternalBuffer(); 
    506     } 
    507  
    508     m_buffer=calloc(m_buffersize,event_size); 
    509     if (!m_buffer) { 
    510         debugFatal("could not allocate internal buffer\n"); 
    511         m_buffersize=0; 
    512         return false; 
    513     } 
    514  
    515     return true; 
    516 } 
    517  
    518 void Port::freeInternalBuffer() { 
    519     debugOutput(DEBUG_LEVEL_VERBOSE, 
    520                 "Freeing internal buffer (%s)\n",m_Name.c_str()); 
    521  
    522     if(m_buffer) { 
    523         free(m_buffer); 
    524         m_buffer=0; 
    525     } 
    526 } 
    527  
    528 bool Port::allocateInternalRingBuffer() { 
    529     int event_size=getEventSize(); 
    530  
    531     debugOutput(DEBUG_LEVEL_VERBOSE, 
    532                 "Allocating internal buffer of %d events with size %d (%s)\n", 
    533                 m_buffersize, event_size, m_Name.c_str()); 
    534  
    535     if(m_ringbuffer) { 
    536         debugWarning("already has an internal ringbuffer attached, re-allocating\n"); 
    537         freeInternalRingBuffer(); 
    538     } 
    539  
    540     m_ringbuffer=ffado_ringbuffer_create(m_buffersize * event_size); 
    541     if (!m_ringbuffer) { 
    542         debugFatal("could not allocate internal ringbuffer\n"); 
    543         m_buffersize=0; 
    544         return false; 
    545     } 
    546  
    547     return true; 
    548 } 
    549  
    550 void Port::freeInternalRingBuffer() { 
    551     debugOutput(DEBUG_LEVEL_VERBOSE, 
    552                 "Freeing internal ringbuffer (%s)\n",m_Name.c_str()); 
    553  
    554     if(m_ringbuffer) { 
    555         ffado_ringbuffer_free(m_ringbuffer); 
    556         m_ringbuffer=0; 
    557     } 
    558136} 
    559137 
    560138void Port::show() { 
    561139    debugOutput(DEBUG_LEVEL_VERBOSE,"Name          : %s\n", m_Name.c_str()); 
    562     debugOutput(DEBUG_LEVEL_VERBOSE,"Signal Type   : %d\n", m_SignalType); 
    563     debugOutput(DEBUG_LEVEL_VERBOSE,"Buffer Type   : %d\n", m_BufferType); 
    564140    debugOutput(DEBUG_LEVEL_VERBOSE,"Enabled?      : %d\n", m_disabled); 
    565141    debugOutput(DEBUG_LEVEL_VERBOSE,"State?        : %d\n", m_State); 
    566142    debugOutput(DEBUG_LEVEL_VERBOSE,"Buffer Size   : %d\n", m_buffersize); 
    567     debugOutput(DEBUG_LEVEL_VERBOSE,"Event Size    : %d\n", m_eventsize); 
    568     debugOutput(DEBUG_LEVEL_VERBOSE,"Data Type     : %d\n", m_DataType); 
     143    debugOutput(DEBUG_LEVEL_VERBOSE,"Event Size    : %d\n", getEventSize()); 
    569144    debugOutput(DEBUG_LEVEL_VERBOSE,"Port Type     : %d\n", m_PortType); 
    570145    debugOutput(DEBUG_LEVEL_VERBOSE,"Direction     : %d\n", m_Direction); 
    571     debugOutput(DEBUG_LEVEL_VERBOSE,"Rate Control? : %d\n", m_do_ratecontrol); 
    572146} 
    573147 
  • trunk/libffado/src/libstreaming/generic/Port.h

    r742 r833  
    3333 
    3434namespace Streaming { 
     35class PortManager; 
    3536 
    3637/*! 
     
    5354       OK. 
    5455 
    55  \todo rework the implementation into something more beautifull 
    5656*/ 
    5757class Port { 
    5858 
    5959public: 
    60     friend class PortManager; 
    61  
    62     /* 
    63      * IMPORTANT: if you add something to any of these enum's, be sure to 
    64      *            check the code where they are used. 
    65      */ 
    66  
    67     /*! 
    68     \brief Specifies the buffer type for ports 
    69  
    70     A PointerBuffer uses the getBufferAddress() and setBufferAddres() interface 
    71     A Ringbuffer uses the read/write interface 
    72     */ 
    73     enum E_BufferType { 
    74         E_PointerBuffer, 
    75         E_RingBuffer 
    76     }; 
    77  
    78     /*! 
    79     \brief Specifies the signalling type for ports 
    80     */ 
    81     enum E_SignalType { 
    82         E_PacketSignalled, ///< the port is to be processed for every packet 
    83         E_PeriodSignalled, ///< the port is to be processed after a period of frames 
    84 //         E_SampleSignalled ///< the port is to be processed after each frame (sample) 
    85     }; 
    86  
    87     /*! 
    88     \brief The datatype of the port buffer 
    89     */ 
    90     enum E_DataType { 
    91         E_Float, 
    92         E_Int24, 
    93         E_MidiEvent, 
    94         E_Default, 
    95     }; 
    96  
    9760    /*! 
    9861    \brief The port type 
     
    11275    }; 
    11376 
    114     Port(std::string name, enum E_PortType porttype, enum E_Direction direction); 
    115  
    116     virtual ~Port() 
    117       {}; 
     77    Port(PortManager&, std::string name, enum E_PortType, enum E_Direction); 
     78 
     79    virtual ~Port(); 
    11880 
    11981 
     
    142104    unsigned int getEventSize(); 
    143105 
    144     /** 
    145      * \brief sets the event type for the port buffer 
    146      * 
    147      * \note use before calling init() 
    148      */ 
    149     virtual bool setDataType(enum E_DataType); 
    150  
    151     enum E_DataType getDataType() {return m_DataType;}; 
    152  
    153     /** 
    154      * \brief sets the event type for the port buffer 
    155      * 
    156      * \note use before calling init() 
    157      */ 
    158     virtual bool setSignalType(enum E_SignalType ); 
    159  
    160     enum E_SignalType getSignalType() {return m_SignalType;}; ///< returns the signalling type of the port 
    161  
    162     /** 
    163      * \brief sets the buffer type for the port 
    164      * 
    165      * \note use before calling init() 
    166      */ 
    167     virtual bool setBufferType(enum E_BufferType ); 
    168  
    169     enum E_BufferType getBufferType() {return m_BufferType;}; ///< returns the buffer type of the port 
    170  
    171106    enum E_PortType getPortType() {return m_PortType;}; ///< returns the port type (is fixed) 
    172107    enum E_Direction getDirection() {return m_Direction;}; ///< returns the direction (is fixed) 
     
    193128    virtual bool setBufferSize(unsigned int); 
    194129 
    195     /** 
    196      * \brief use an external buffer (or not) 
    197      * 
    198      * \note use before calling init() 
    199      */ 
    200     virtual bool useExternalBuffer(bool b); 
    201  
    202     void setExternalBufferAddress(void *buff); 
    203  
    204  
    205     /** 
    206      * \brief enable/disable ratecontrol 
    207      * 
    208      * Rate control is nescessary for some types of ports (most notably 
    209      * midi). The StreamProcessor that handles the port should call canRead() 
    210      * everytime a 'slot' that could be filled with an event passes. The canRead 
    211      * function will return true if 
    212      *  (1) there is an event ready in the buffer 
    213      *  (2) we are allowed to send an event in this slot 
    214      * 
    215      * Setting the rate works is done with the slot_interval and the event_interval 
    216      * parameters. On every call to canRead(), a counter is decremented with 
    217      * slot_interval. If the counter drops below 0, canRead() returns true and resets 
    218      * the counter to event_interval. 
    219      * 
    220      * e.g. for AMDTP midi, we are only allowed to send a midi byte every 320us 
    221      *      if the SYT interval is 8, there is exactly one midi slot every packet. 
    222      *    therefore the slot_interval is 1/8000s (=125us), and the event_interval 
    223      *      is 320us. 
    224      * 
    225      *      Note that the interval parameters are unitless, so you can adapt them 
    226      *      to your needs. In the AMDTP case for example, when the SYT interval is 32 
    227      *      (when the samplerate is 192kHz for example) there are 4 midi slots in 
    228      *      each packet, making the slot time interval 125us/4 = 31.25us. 
    229      *      The event time interval stays the same (320us). We can however set the 
    230      *    slot_interval to 3125 and the event_interval to 32000, as we can choose 
    231      *    the unit of the counter time step (chosen to be 10ns in this case). 
    232      * 
    233      * The average argument deserves some attention too. If average is true, we use 
    234      * average rate control. This means that on average there will be a delay of 
    235      * event_interval between two events, but that sometimes there can be a smaller 
    236      * delay. This mode fixes the average rate of the stream. 
    237      * If average is false, there will always be a minimal delay of event_interval 
    238      * between two events. This means that the maximum rate of the stream is fixed, 
    239      * and that the average rate will be lower than (or at max equal to) the rate in 
    240      * average mode. 
    241      * 
    242      * 
    243      * \note only works for the E_RingBuffer ports 
    244      * \note use before calling init() 
    245      * 
    246      * @param use set this to true to use rate control 
    247      * @param slot_interval the interval between slots 
    248      * @param event_interval the interval between events 
    249      * @param average use average rate control 
    250      * @return true if rate control was enabled/disabled successfully 
    251      */ 
    252     virtual bool useRateControl(bool use, unsigned int slot_interval, 
    253                                 unsigned int event_interval, bool average); 
    254  
    255     bool usingRateControl() { return m_do_ratecontrol;}; ///< are we using rate control? 
    256  
    257     /** 
    258      * Can we send an event in this slot. subject to rate control and 
    259      * byte availability. 
    260      * @return true if we can send an event on this slot 
    261      */ 
    262     bool canRead(); 
    263  
    264     // FIXME: this is not really OO, but for performance??? 
     130    void setBufferAddress(void *buff); 
    265131    void *getBufferAddress(); 
    266132 
    267     // TODO: extend this with a blocking interface 
    268     bool writeEvent(void *event); ///< write one event 
    269     bool readEvent(void *event); ///< read one event 
    270     int writeEvents(void *event, unsigned int nevents); ///< write multiple events 
    271     int readEvents(void *event, unsigned int nevents); ///< read multiple events 
     133    PortManager& getManager() { return m_manager; }; 
    272134 
    273135    virtual void setVerboseLevel(int l); 
    274136    virtual void show(); 
    275      
     137 
    276138protected: 
    277139    std::string m_Name; ///< Port name, [at construction] 
    278  
    279     enum E_SignalType m_SignalType; ///< Signalling type, [at construction] 
    280     enum E_BufferType m_BufferType; ///< Buffer type, [at construction] 
    281  
    282140    bool m_disabled; ///< is the port disabled?, [anytime] 
    283141 
    284142    unsigned int m_buffersize; 
    285     unsigned int m_eventsize; 
    286  
    287     enum E_DataType m_DataType; 
     143 
    288144    enum E_PortType m_PortType; 
    289145    enum E_Direction m_Direction; 
    290146 
    291147    void *m_buffer; 
    292     ffado_ringbuffer_t *m_ringbuffer; 
    293     bool m_use_external_buffer; 
    294  
    295     bool m_do_ratecontrol; 
    296     int m_event_interval; 
    297     int m_slot_interval; 
    298     int m_rate_counter; 
    299     int m_rate_counter_minimum; 
    300     bool m_average_ratecontrol; 
    301  
    302     bool allocateInternalBuffer(); 
    303     void freeInternalBuffer(); 
    304  
    305     bool allocateInternalRingBuffer(); 
    306     void freeInternalRingBuffer(); 
     148 
     149    PortManager& m_manager; 
    307150 
    308151    DECLARE_DEBUG_MODULE; 
    309      
    310     // the state machine 
    311     protected: 
    312         enum EStates { 
    313             E_Created, 
    314             E_Initialized, 
    315             E_Prepared, 
    316             E_Running, 
    317             E_Error 
    318         }; 
    319  
    320         enum EStates m_State; 
     152 
     153// the state machine 
     154protected: 
     155    enum EStates { 
     156        E_Created, 
     157        E_Initialized, 
     158        E_Prepared, 
     159        E_Running, 
     160        E_Error 
     161    }; 
     162 
     163    enum EStates m_State; 
    321164}; 
    322165 
     
    330173public: 
    331174 
    332     AudioPort(std::string name, enum E_Direction direction) 
    333       : Port(name, E_Audio, direction) 
     175    AudioPort(PortManager& m, std::string name, enum E_Direction direction) 
     176      : Port(m, name, E_Audio, direction) 
    334177    {}; 
    335178 
    336179    virtual ~AudioPort() {}; 
    337  
    338 protected: 
    339  
    340  
    341180}; 
    342181 
     
    350189public: 
    351190 
    352     MidiPort(std::string name, enum E_Direction direction) 
    353       : Port(name, E_Midi, direction) 
     191    MidiPort(PortManager& m, std::string name, enum E_Direction direction) 
     192      : Port(m, name, E_Midi, direction) 
    354193    {}; 
    355194    virtual ~MidiPort() {}; 
    356  
    357  
    358 protected: 
    359  
    360  
    361195}; 
    362196 
     
    370204public: 
    371205 
    372     ControlPort(std::string name, enum E_Direction direction) 
    373       : Port(name, E_Control, direction) 
     206    ControlPort(PortManager& m, std::string name, enum E_Direction direction) 
     207      : Port(m, name, E_Control, direction) 
    374208    {}; 
    375209    virtual ~ControlPort() {}; 
    376  
    377  
    378 protected: 
    379  
    380  
    381210}; 
    382211 
  • trunk/libffado/src/libstreaming/generic/PortManager.cpp

    r750 r833  
    3636 
    3737PortManager::PortManager() { 
    38  
    3938} 
    4039 
    4140PortManager::~PortManager() { 
    42 //     deleteAllPorts(); 
    43 
    44  
    45 // bool PortManager::setPortBuffersize(unsigned int newsize) { 
    46 //     debugOutput( DEBUG_LEVEL_VERBOSE, "setting port buffer size to %d\n",newsize); 
    47 // 
    48 // 
    49 //     for ( PortVectorIterator it = m_Ports.begin(); 
    50 //       it != m_Ports.end(); 
    51 //       ++it ) 
    52 //     { 
    53 //         if(!(*it)->setBufferSize(newsize)) { 
    54 //             debugFatal("Could not set buffer size for port %s\n",(*it)->getName().c_str()); 
    55 //             return false; 
    56 //         } 
    57 //     } 
    58 // 
    59 //     return true; //not found 
    60 // 
    61 // } 
     41    flushDebugOutput(); 
     42    // delete all ports that are still registered to the manager 
     43    for ( PortVectorIterator it = m_Ports.begin(); 
     44    it != m_Ports.end(); 
     45    ++it ) 
     46    { 
     47        debugOutput( DEBUG_LEVEL_VERBOSE, "deleting port %s at %p\n", (*it)->getName().c_str(), *it); 
     48        flushDebugOutput(); 
     49        delete *it; //FIXME 
     50    } 
     51
    6252 
    6353bool PortManager::makeNameUnique(Port *port) 
     
    9686 * @return 
    9787 */ 
    98 bool PortManager::addPort(Port *port) 
     88bool PortManager::registerPort(Port *port) 
    9989{ 
    10090    assert(port); 
    10191 
    102     debugOutput( DEBUG_LEVEL_VERBOSE, "Adding port %s, type: %d, dir: %d, dtype: %d\n", 
    103         port->getName().c_str(), port->getPortType(), port->getDirection(), port->getDataType()); 
     92    debugOutput( DEBUG_LEVEL_VERBOSE, "Adding port %s, type: %d, dir: %d\n", 
     93        port->getName().c_str(), port->getPortType(), port->getDirection()); 
    10494 
    10595    port->setVerboseLevel(getDebugLevel()); 
     
    113103} 
    114104 
    115 bool PortManager::deletePort(Port *port) 
     105bool PortManager::unregisterPort(Port *port) 
    116106{ 
    117107    assert(port); 
    118     debugOutput( DEBUG_LEVEL_VERBOSE, "deleting port %s\n",port->getName().c_str()); 
     108    debugOutput( DEBUG_LEVEL_VERBOSE, "unregistering port %s\n",port->getName().c_str()); 
    119109 
    120110    for ( PortVectorIterator it = m_Ports.begin(); 
     
    124114        if(*it == port) { 
    125115            m_Ports.erase(it); 
    126 //             delete *it; 
    127116            return true; 
    128117        } 
     
    132121 
    133122    return false; //not found 
    134  
    135 } 
    136  
    137 void PortManager::deleteAllPorts() 
    138 { 
    139     debugOutput( DEBUG_LEVEL_VERBOSE, "deleting all ports\n"); 
    140  
    141     for ( PortVectorIterator it = m_Ports.begin(); 
    142       it != m_Ports.end(); 
    143       ++it ) 
    144     { 
    145         m_Ports.erase(it); 
    146 //         delete *it; 
    147     } 
    148  
    149     return; 
    150123 
    151124} 
     
    213186    { 
    214187        if(!(*it)->init()) { 
    215             debugFatal("Could not init port %s",(*it)->getName().c_str()); 
     188            debugFatal("Could not init port %s\n", (*it)->getName().c_str()); 
    216189            return false; 
    217190        } 
     
    222195bool PortManager::preparePorts() { 
    223196    debugOutput( DEBUG_LEVEL_VERBOSE, "preparing ports\n"); 
    224  
    225     // clear the cache lists 
    226     m_PeriodPorts.clear(); 
    227     m_PacketPorts.clear(); 
    228197 
    229198    for ( PortVectorIterator it = m_Ports.begin(); 
     
    236205        } 
    237206 
    238         // now prepare the cache lists 
    239         switch((*it)->getSignalType()) { 
    240             case Port::E_PacketSignalled: 
    241                 m_PacketPorts.push_back(*it); 
    242                 break; 
    243             case Port::E_PeriodSignalled: 
    244                 m_PeriodPorts.push_back(*it); 
    245                 break; 
    246             default: 
    247                 debugWarning("%s has unsupported port type\n", 
    248                              (*it)->getName().c_str()); 
    249             break; 
    250         } 
    251207    } 
    252208    return true; 
  • trunk/libffado/src/libstreaming/generic/PortManager.h

    r742 r833  
    3333namespace Streaming { 
    3434 
    35 class Port; 
    3635typedef std::vector<Port *> PortVector; 
    3736typedef std::vector<Port *>::iterator PortVectorIterator; 
     
    5049 
    5150    virtual bool makeNameUnique(Port *port); 
    52     virtual bool addPort(Port *port); 
    53     virtual bool deletePort(Port *port); 
    54     virtual void deleteAllPorts(); 
     51    virtual bool registerPort(Port *port); 
     52    virtual bool unregisterPort(Port *port); 
    5553 
    5654    int getPortCount(enum Port::E_PortType); 
    5755    int getPortCount(); 
    58  
    59 //     virtual bool setPortBuffersize(unsigned int newsize); 
    6056 
    6157    Port *getPortAtIdx(unsigned int index); 
     
    6965protected: 
    7066    PortVector m_Ports; 
    71     PortVector m_PacketPorts; 
    72     PortVector m_PeriodPorts; 
    73 //     PortVector m_SamplePorts; 
    7467 
    7568    DECLARE_DEBUG_MODULE; 
    76  
    7769}; 
    7870 
  • trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp

    r807 r833  
    6666    , m_IsoHandlerManager( parent.get1394Service().getIsoHandlerManager() ) // local cache 
    6767    , m_StreamProcessorManager( m_Parent.getDeviceManager().getStreamProcessorManager() ) // local cache 
     68    , m_local_node_id ( 0 ) // local cache 
    6869    , m_channel( -1 ) 
    69     , m_dropped(0) 
    70     , m_last_timestamp(0) 
    71     , m_last_timestamp2(0) 
     70    , m_dropped( 0 ) 
     71    , m_last_timestamp( 0 ) 
     72    , m_last_timestamp2( 0 ) 
     73    , m_correct_last_timestamp( false ) 
    7274    , m_scratch_buffer( NULL ) 
    7375    , m_scratch_buffer_size_bytes( 0 ) 
     
    8890        debugOutput(DEBUG_LEVEL_VERBOSE,"Could not unregister stream processor with the Iso manager\n"); 
    8991    } 
     92    // make the threads leave the wait condition 
     93    POST_SEMAPHORE; 
     94    sem_destroy(&m_signal_semaphore); 
    9095 
    9196    if (m_data_buffer) delete m_data_buffer; 
    9297    if (m_scratch_buffer) delete[] m_scratch_buffer; 
    93     sem_destroy(&m_signal_semaphore); 
    9498} 
    9599 
     
    130134    // the waitForClient in IsoHandler will take care of the fact that the frames are 
    131135    // not present in time 
    132     unsigned int packets_to_prebuffer = (getPacketsPerPeriod() * (m_StreamProcessorManager.getNbBuffers()))
     136    unsigned int packets_to_prebuffer = (getPacketsPerPeriod() * (m_StreamProcessorManager.getNbBuffers())) + 10
    133137    debugOutput(DEBUG_LEVEL_VERBOSE, "Nominal prebuffer: %u\n", packets_to_prebuffer); 
    134138    return packets_to_prebuffer; 
     
    286290                           unsigned char channel, unsigned char tag, unsigned char sy, 
    287291                           unsigned int cycle, unsigned int dropped) { 
     292#ifdef DEBUG 
    288293    if(m_last_cycle == -1) { 
    289294        debugOutput(DEBUG_LEVEL_VERBOSE, "Handler for %s SP %p is alive (cycle = %u)\n", getTypeString(), this, cycle); 
    290295    } 
     296#endif 
    291297 
    292298    int dropped_cycles = 0; 
     
    301307                this, dropped_cycles, cycle, dropped, cycle, m_last_cycle); 
    302308            m_dropped += dropped_cycles; 
    303             m_in_xrun = true; 
    304309            m_last_cycle = cycle; 
    305             POST_SEMAPHORE; 
    306             return RAW1394_ISO_DEFER; 
    307             //flushDebugOutput(); 
    308             //assert(0); 
    309310        } 
    310311    } 
     
    344345        // the received data can be discarded while waiting for the stream 
    345346        // to be disabled 
     347        // similarly for dropped packets 
    346348        return RAW1394_ISO_OK; 
    347349    } 
     
    366368    // check the packet header 
    367369    enum eChildReturnValue result = processPacketHeader(data, length, channel, tag, sy, cycle, dropped_cycles); 
     370 
     371    // handle dropped cycles 
     372    if(dropped_cycles) { 
     373        // make sure the last_timestamp is corrected 
     374        m_correct_last_timestamp = true; 
     375        if (m_state == ePS_Running) { 
     376            // this is an xrun situation 
     377            m_in_xrun = true; 
     378            debugWarning("Should update state to WaitingForStreamDisable due to dropped packet xrun\n"); 
     379            m_cycle_to_switch_state = cycle + 1; // switch in the next cycle 
     380            m_next_state = ePS_WaitingForStreamDisable; 
     381            // execute the requested change 
     382            if (!updateState()) { // we are allowed to change the state directly 
     383                debugError("Could not update state!\n"); 
     384                POST_SEMAPHORE; 
     385                return RAW1394_ISO_ERROR; 
     386            } 
     387        } 
     388    } 
     389 
    368390    if (result == eCRV_OK) { 
    369391        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "RECV: CY=%04u TS=%011llu\n", 
     
    372394        m_last_good_cycle = cycle; 
    373395        m_last_dropped = dropped_cycles; 
     396 
     397        if(m_correct_last_timestamp) { 
     398            // they represent a discontinuity in the timestamps, and hence are 
     399            // to be dealt with 
     400            debugWarning("(%p) Correcting timestamp for dropped cycles, discarding packet...\n", this); 
     401            m_data_buffer->setBufferTailTimestamp(substractTicks(m_last_timestamp, getNominalFramesPerPacket() * getTicksPerFrame())); 
     402            m_correct_last_timestamp = false; 
     403        } 
    374404 
    375405        // check whether we are waiting for a stream to startup 
     
    406436                POST_SEMAPHORE; 
    407437                return RAW1394_ISO_ERROR; 
    408             } 
    409         } 
    410  
    411         // handle dropped cycles 
    412         if(dropped_cycles) { 
    413             // they represent a discontinuity in the timestamps, and hence are 
    414             // to be dealt with 
    415             debugWarning("(%p) Correcting timestamp for dropped cycles, discarding packet...\n", this); 
    416             m_data_buffer->setBufferTailTimestamp(m_last_timestamp); 
    417             if (m_state == ePS_Running) { 
    418                 // this is an xrun situation 
    419                 m_in_xrun = true; 
    420                 debugWarning("Should update state to WaitingForStreamDisable due to dropped packet xrun\n"); 
    421                 m_cycle_to_switch_state = cycle + 1; // switch in the next cycle 
    422                 m_next_state = ePS_WaitingForStreamDisable; 
    423                 // execute the requested change 
    424                 if (!updateState()) { // we are allowed to change the state directly 
    425                     debugError("Could not update state!\n"); 
    426                     POST_SEMAPHORE; 
    427                     return RAW1394_ISO_ERROR; 
    428                 } 
    429                 POST_SEMAPHORE; 
    430                 return RAW1394_ISO_DEFER; 
    431438            } 
    432439        } 
     
    466473                    unsigned int signal_period = m_signal_period * (semval + 1) + m_signal_offset; 
    467474                    if(bufferfill >= signal_period) { 
    468                         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) buffer fill (%d) > signal period (%d), sem_val=%d\n", 
     475                        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p) buffer fill (%d) > signal period (%d), sem_val=%d\n", 
    469476                                    this, m_data_buffer->getBufferFill(), signal_period, semval); 
    470477                        POST_SEMAPHORE; 
     
    472479                    // the process thread should have higher prio such that we are blocked until 
    473480                    // the samples are processed. 
     481                    return RAW1394_ISO_DEFER; 
    474482                } 
    475483            } 
     
    508516    int cycle_diff; 
    509517 
     518#ifdef DEBUG 
    510519    if(m_last_cycle == -1) { 
    511520        debugOutput(DEBUG_LEVEL_VERBOSE, "Handler for %s SP %p is alive (cycle = %d)\n", getTypeString(), this, cycle); 
    512521    } 
     522#endif 
    513523 
    514524    int dropped_cycles = 0; 
     
    529539                debugWarning("dropped packets xrun\n"); 
    530540                debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to dropped packets xrun\n"); 
     541                m_cycle_to_switch_state = cycle + 1; 
    531542                m_next_state = ePS_WaitingForStreamDisable; 
    532543                // execute the requested change 
     
    543554    } 
    544555 
     556#ifdef DEBUG 
    545557    // bypass based upon state 
    546558    if (m_state == ePS_Invalid) { 
     
    548560        return RAW1394_ISO_ERROR; 
    549561    } 
     562#endif 
     563 
    550564    if (m_state == ePS_Created) { 
    551565        *tag = 0; 
     
    577591            m_in_xrun = true; 
    578592            debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to data xrun\n"); 
     593            m_cycle_to_switch_state = cycle + 1; 
    579594            m_next_state = ePS_WaitingForStreamDisable; 
    580595            // execute the requested change 
     
    670685                m_in_xrun = true; 
    671686                debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to data xrun\n"); 
    672                 m_cycle_to_switch_state = cycle+1; // switch in the next cycle 
     687                m_cycle_to_switch_state = cycle + 1; // switch in the next cycle 
    673688                m_next_state = ePS_WaitingForStreamDisable; 
    674689                // execute the requested change 
     
    689704            m_in_xrun = true; 
    690705            debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to header xrun\n"); 
     706            m_cycle_to_switch_state = cycle + 1; // switch in the next cycle 
    691707            m_next_state = ePS_WaitingForStreamDisable; 
    692708            // execute the requested change 
     
    837853    unsigned int bufferfill = m_data_buffer->getBufferFill(); 
    838854    if (bufferfill >= m_signal_period + m_signal_offset) { 
    839         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) sufficient frames in buffer (%d / %d), posting semaphore\n", 
     855        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p) sufficient frames in buffer (%d / %d), posting semaphore\n", 
    840856                                         this, bufferfill, m_signal_period + m_signal_offset); 
    841857        POST_SEMAPHORE; 
    842858    } else { 
    843         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) insufficient frames in buffer (%d / %d), not posting semaphore\n", 
     859        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p) insufficient frames in buffer (%d / %d), not posting semaphore\n", 
    844860                                         this, bufferfill, m_signal_period + m_signal_offset); 
    845861    } 
     
    894910StreamProcessor::waitForSignal() 
    895911{ 
     912    debugOutput(DEBUG_LEVEL_VERBOSE, "(%p, %s) wait ...\n", this, getTypeString()); 
    896913    int result; 
    897     if(m_state == ePS_Running) { 
     914    if(m_state == ePS_Running && m_next_state == ePS_Running) { 
    898915        result = sem_wait(&m_signal_semaphore); 
    899916#ifdef DEBUG 
    900917        int tmp; 
    901918        sem_getvalue(&m_signal_semaphore, &tmp); 
    902         debugOutput(DEBUG_LEVEL_VERBOSE, " sem_wait returns: %d, sem_value: %d\n", result, tmp); 
     919        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " sem_wait returns: %d, sem_value: %d\n", result, tmp); 
    903920#endif 
    904921        return result == 0; 
    905922    } else { 
    906923        // when we're not running, we can always provide frames 
     924        // when we're in a state transition, keep iterating too 
    907925        debugOutput(DEBUG_LEVEL_VERBOSE, "Not running...\n"); 
    908926        return true; 
     
    925943StreamProcessor::canProcessPackets() 
    926944{ 
    927     if(m_state != ePS_Running) return true; 
     945    if(m_state != ePS_Running || m_next_state != ePS_Running) return true; 
    928946    bool result; 
    929     int bufferfill; 
     947    unsigned int bufferfill; 
    930948    if(getType() == ePT_Receive) { 
    931949        bufferfill = m_data_buffer->getBufferSpace(); 
     
    934952    } 
    935953    result = bufferfill > getNominalFramesPerPacket(); 
    936     debugOutput(DEBUG_LEVEL_VERBOSE, "(%p, %s) for a bufferfill of %d, we return %d\n", 
    937                 this, ePTToString(getType()), bufferfill, result); 
     954//     debugOutput(DEBUG_LEVEL_VERBOSE, "(%p, %s) for a bufferfill of %d, we return %d\n", 
     955//                 this, ePTToString(getType()), bufferfill, result); 
    938956    return result; 
    939957} 
     
    960978{ 
    961979    bool no_problem=true; 
    962     for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    963           it != m_PeriodPorts.end(); 
     980    for ( PortVectorIterator it = m_Ports.begin(); 
     981          it != m_Ports.end(); 
    964982          ++it ) { 
    965983        if((*it)->isDisabled()) {continue;}; 
    966984 
    967         //FIXME: make this into a static_cast when not DEBUG? 
    968         Port *port=dynamic_cast<Port *>(*it); 
    969  
    970         switch(port->getPortType()) { 
    971  
    972         case Port::E_Audio: 
    973             if(provideSilenceToPort(static_cast<AudioPort *>(*it), offset, nevents)) { 
    974                 debugWarning("Could not put silence into to port %s",(*it)->getName().c_str()); 
    975                 no_problem=false; 
    976             } 
    977             break; 
    978         // midi is a packet based port, don't process 
    979         //    case MotuPortInfo::E_Midi: 
    980         //        break; 
    981  
    982         default: // ignore 
    983             break; 
     985        if(provideSilenceToPort((*it), offset, nevents)) { 
     986            debugWarning("Could not put silence into to port %s",(*it)->getName().c_str()); 
     987            no_problem=false; 
    984988        } 
    985989    } 
     
    988992 
    989993int 
    990 StreamProcessor::provideSilenceToPort( 
    991                        AudioPort *p, unsigned int offset, unsigned int nevents) 
     994StreamProcessor::provideSilenceToPort(Port *p, unsigned int offset, unsigned int nevents) 
    992995{ 
    993996    unsigned int j=0; 
    994     switch(p->getDataType()) { 
     997    switch(p->getPortType()) { 
    995998        default: 
    996         case Port::E_Int24: 
     999            debugError("Invalid port type: %d\n", p->getPortType()); 
     1000            return -1; 
     1001        case Port::E_Midi: 
     1002        case Port::E_Control: 
    9971003            { 
    9981004                quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress()); 
     
    10001006                buffer+=offset; 
    10011007 
    1002                 for(j = 0; j < nevents; j += 1) { // decode max nsamples 
     1008                for(j = 0; j < nevents; j += 1) { 
    10031009                    *(buffer)=0; 
    10041010                    buffer++; 
     
    10061012            } 
    10071013            break; 
    1008         case Port::E_Float: 
    1009             { 
    1010                 float *buffer=(float *)(p->getBufferAddress()); 
    1011                 assert(nevents + offset <= p->getBufferSize()); 
    1012                 buffer+=offset; 
    1013  
    1014                 for(j = 0; j < nevents; j += 1) { // decode max nsamples 
    1015                     *buffer = 0.0; 
    1016                     buffer++; 
     1014        case Port::E_Audio: 
     1015            switch(m_StreamProcessorManager.getAudioDataType()) { 
     1016            case StreamProcessorManager::eADT_Int24: 
     1017                { 
     1018                    quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress()); 
     1019                    assert(nevents + offset <= p->getBufferSize()); 
     1020                    buffer+=offset; 
     1021     
     1022                    for(j = 0; j < nevents; j += 1) { 
     1023                        *(buffer)=0; 
     1024                        buffer++; 
     1025                    } 
    10171026                } 
     1027                break; 
     1028            case StreamProcessorManager::eADT_Float: 
     1029                { 
     1030                    float *buffer=(float *)(p->getBufferAddress()); 
     1031                    assert(nevents + offset <= p->getBufferSize()); 
     1032                    buffer+=offset; 
     1033     
     1034                    for(j = 0; j < nevents; j += 1) { 
     1035                        *buffer = 0.0; 
     1036                        buffer++; 
     1037                    } 
     1038                } 
     1039                break; 
    10181040            } 
    10191041            break; 
     
    10631085    } 
    10641086 
     1087    // set the parameters of ports we can: 
     1088    // we want the audio ports to be period buffered, 
     1089    // and the midi ports to be packet buffered 
     1090    for ( PortVectorIterator it = m_Ports.begin(); 
     1091        it != m_Ports.end(); 
     1092        ++it ) 
     1093    { 
     1094        debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str()); 
     1095        if(!(*it)->setBufferSize(m_StreamProcessorManager.getPeriodSize())) { 
     1096            debugFatal("Could not set buffer size to %d\n",m_StreamProcessorManager.getPeriodSize()); 
     1097            return false; 
     1098        } 
     1099    } 
     1100    // the API specific settings of the ports should already be set, 
     1101    // as this is called from the processorManager->prepare() 
     1102    // so we can init the ports 
     1103    if(!PortManager::initPorts()) { 
     1104        debugFatal("Could not initialize ports\n"); 
     1105        return false; 
     1106    } 
     1107 
    10651108    if (!prepareChild()) { 
    10661109        debugFatal("Could not prepare child\n"); 
     
    10891132    m_cycle_to_switch_state = TICKS_TO_CYCLES(time_instant); 
    10901133    m_next_state = state; 
     1134    POST_SEMAPHORE; // needed to ensure that things don't get deadlocked 
    10911135    return true; 
    10921136} 
     
    12861330        case ePS_Created: 
    12871331            assert(m_data_buffer); 
    1288             // object just created 
    1289             result = m_data_buffer->init(); 
    12901332 
    12911333            // prepare the framerate estimate 
    12921334            ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_StreamProcessorManager.getNominalRate()); 
    12931335            m_ticks_per_frame = ticks_per_frame; 
     1336            m_local_node_id= m_1394service.getLocalNodeId() & 0x3f; 
     1337            m_correct_last_timestamp = false; 
     1338 
    12941339            debugOutput(DEBUG_LEVEL_VERBOSE,"Initializing remote ticks/frame to %f\n", ticks_per_frame); 
    12951340 
     
    13071352            result &= m_data_buffer->setWrapValue(128L*TICKS_PER_SECOND); 
    13081353            result &= m_data_buffer->prepare(); // FIXME: the name 
    1309  
    1310             // set the parameters of ports we can: 
    1311             // we want the audio ports to be period buffered, 
    1312             // and the midi ports to be packet buffered 
    1313             for ( PortVectorIterator it = m_Ports.begin(); 
    1314                 it != m_Ports.end(); 
    1315                 ++it ) 
    1316             { 
    1317                 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str()); 
    1318                 if(!(*it)->setBufferSize(m_StreamProcessorManager.getPeriodSize())) { 
    1319                     debugFatal("Could not set buffer size to %d\n",m_StreamProcessorManager.getPeriodSize()); 
    1320                     return false; 
    1321                 } 
    1322                 switch ((*it)->getPortType()) { 
    1323                     case Port::E_Audio: 
    1324                         if(!(*it)->setSignalType(Port::E_PeriodSignalled)) { 
    1325                             debugFatal("Could not set signal type to PeriodSignalling"); 
    1326                             return false; 
    1327                         } 
    1328                         // buffertype and datatype are dependant on the API 
    1329                         debugWarning("---------------- ! Doing hardcoded dummy setup ! --------------\n"); 
    1330                         // buffertype and datatype are dependant on the API 
    1331                         if(!(*it)->setBufferType(Port::E_PointerBuffer)) { 
    1332                             debugFatal("Could not set buffer type"); 
    1333                             return false; 
    1334                         } 
    1335                         if(!(*it)->useExternalBuffer(true)) { 
    1336                             debugFatal("Could not set external buffer usage"); 
    1337                             return false; 
    1338                         } 
    1339                         if(!(*it)->setDataType(Port::E_Float)) { 
    1340                             debugFatal("Could not set data type"); 
    1341                             return false; 
    1342                         } 
    1343                         break; 
    1344                     case Port::E_Midi: 
    1345                         if(!(*it)->setSignalType(Port::E_PacketSignalled)) { 
    1346                             debugFatal("Could not set signal type to PacketSignalling"); 
    1347                             return false; 
    1348                         } 
    1349                         // buffertype and datatype are dependant on the API 
    1350                         debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n"); 
    1351                         // buffertype and datatype are dependant on the API 
    1352                         if(!(*it)->setBufferType(Port::E_RingBuffer)) { 
    1353                             debugFatal("Could not set buffer type"); 
    1354                             return false; 
    1355                         } 
    1356                         if(!(*it)->setDataType(Port::E_MidiEvent)) { 
    1357                             debugFatal("Could not set data type"); 
    1358                             return false; 
    1359                         } 
    1360                         break; 
    1361                     default: 
    1362                         debugWarning("Unsupported port type specified\n"); 
    1363                         break; 
    1364                 } 
    1365             } 
    1366             // the API specific settings of the ports should already be set, 
    1367             // as this is called from the processorManager->prepare() 
    1368             // so we can init the ports 
    1369             result &= PortManager::initPorts(); 
    13701354 
    13711355            break; 
     
    14491433            // a running stream has been detected 
    14501434            debugOutput(DEBUG_LEVEL_VERBOSE, "StreamProcessor %p started dry-running at cycle %d\n", this, m_last_cycle); 
     1435            m_local_node_id = m_1394service.getLocalNodeId() & 0x3f; 
    14511436            if (getType() == ePT_Receive) { 
    14521437                // this to ensure that there is no discontinuity when starting to  
     
    15551540                                             this, m_last_cycle); 
    15561541            m_in_xrun = false; 
     1542            m_local_node_id = m_1394service.getLocalNodeId() & 0x3f; 
    15571543            m_data_buffer->setTransparent(false); 
    15581544            break; 
     
    16321618        // do init here  
    16331619        result = doStop(); 
    1634         if (result) return true; 
     1620        if (result) {POST_SEMAPHORE; return true;} 
    16351621        else goto updateState_exit_change_failed; 
    16361622    } 
     
    16421628        } 
    16431629        result = doWaitForRunningStream(); 
    1644         if (result) return true; 
     1630        if (result) {POST_SEMAPHORE; return true;} 
    16451631        else goto updateState_exit_change_failed; 
    16461632    } 
     
    16531639        } 
    16541640        result = doDryRunning(); 
    1655         if (result) return true; 
     1641        if (result) {POST_SEMAPHORE; return true;} 
    16561642        else goto updateState_exit_change_failed; 
    16571643    } 
     
    16701656            result = doWaitForStreamEnable(); 
    16711657        } 
    1672         if (result) return true; 
     1658        if (result) {POST_SEMAPHORE; return true;} 
    16731659        else goto updateState_exit_change_failed; 
    16741660    } 
     
    16871673            result = doRunning(); 
    16881674        } 
    1689         if (result) return true; 
     1675        if (result) {POST_SEMAPHORE; return true;} 
    16901676        else goto updateState_exit_change_failed; 
    16911677    } 
     
    16971683        } 
    16981684        result = doWaitForStreamDisable(); 
    1699         if (result) return true; 
     1685        if (result) {POST_SEMAPHORE; return true;} 
    17001686        else goto updateState_exit_change_failed; 
    17011687    } 
     
    17071693        } 
    17081694        result = doDryRunning(); 
    1709         if (result) return true; 
     1695        if (result) {POST_SEMAPHORE; return true;} 
    17101696        else goto updateState_exit_change_failed; 
    17111697    } 
     
    17151701    debugError("Invalid state transition: %s => %s\n", 
    17161702        ePSToString(m_state), ePSToString(next_state)); 
     1703    POST_SEMAPHORE; 
    17171704    return false; 
    17181705updateState_exit_change_failed: 
    17191706    debugError("State transition failed: %s => %s\n", 
    17201707        ePSToString(m_state), ePSToString(next_state)); 
     1708    POST_SEMAPHORE; 
    17211709    return false; 
    17221710} 
  • trunk/libffado/src/libstreaming/generic/StreamProcessor.h

    r807 r833  
    137137    IsoHandlerManager&          m_IsoHandlerManager; 
    138138    StreamProcessorManager&     m_StreamProcessorManager; 
     139    unsigned int                m_local_node_id; 
    139140 
    140141public: // the public receive/transmit functions 
     
    292293        {debugWarning("call not allowed\n"); return false;}; 
    293294protected: // some generic helpers 
    294     int provideSilenceToPort(AudioPort *p, unsigned int offset, unsigned int nevents); 
     295    int provideSilenceToPort(Port *p, unsigned int offset, unsigned int nevents); 
    295296    bool provideSilenceBlock(unsigned int nevents, unsigned int offset); 
    296297 
     
    325326    uint64_t m_last_timestamp; /// last timestamp (in ticks) 
    326327    uint64_t m_last_timestamp2; /// last timestamp (in ticks) 
    327     uint64_t m_last_timestamp_at_period_ticks; 
     328    bool m_correct_last_timestamp; 
     329    uint64_t m_last_timestamp_at_period_ticks; // FIXME: still used? 
    328330 
    329331//--- data buffering and accounting 
  • trunk/libffado/src/libstreaming/motu/MotuPort.h

    r742 r833  
    4848public: 
    4949 
    50     MotuAudioPort(std::string name, 
    51                        enum E_Direction direction, 
    52                    int position, 
    53                    int size) 
    54     : AudioPort(name, direction), 
     50    MotuAudioPort(PortManager &m, 
     51                  std::string name, 
     52                  enum E_Direction direction, 
     53                  int position, 
     54                  int size) 
     55    : AudioPort(m, name, direction), 
    5556      MotuPortInfo( position, size) // TODO: add more port information parameters here if nescessary 
    5657    {}; 
    5758 
    5859    virtual ~MotuAudioPort() {}; 
    59  
    60 protected: 
    61  
    6260}; 
    6361 
     
    7371public: 
    7472 
    75     MotuMidiPort(std::string name, 
    76                        enum E_Direction direction, 
    77                    int position) 
    78         : MidiPort(name, direction), 
     73    MotuMidiPort(PortManager &m, 
     74                 std::string name, 
     75                 enum E_Direction direction, 
     76                 int position) 
     77        : MidiPort(m, name, direction), 
    7978          MotuPortInfo(position, 0)  // TODO: add more port information parameters here if nescessary 
    8079    {}; 
    8180 
    82  
    8381    virtual ~MotuMidiPort() {}; 
    84  
    85 protected: 
    86  
    8782}; 
    8883 
     
    9893public: 
    9994 
    100     MotuControlPort(std::string name, 
    101                        enum E_Direction direction, 
    102                    int position) 
    103         : ControlPort(name, direction), 
     95    MotuControlPort(PortManager &m, 
     96                    std::string name, 
     97                    enum E_Direction direction, 
     98                    int position) 
     99        : ControlPort(m, name, direction), 
    104100          MotuPortInfo(position, 2) // TODO: add more port information parameters here if nescessary 
    105101    {}; 
    106102 
    107  
    108103    virtual ~MotuControlPort() {}; 
    109  
    110 protected: 
    111  
    112104}; 
    113105 
  • trunk/libffado/src/libstreaming/motu/MotuReceiveStreamProcessor.cpp

    r750 r833  
    187187 
    188188    if(m_data_buffer->writeFrames(n_events, (char *)(data+8), m_last_timestamp)) { 
    189         int dbc = get_bits(ntohl(quadlet[0]), 8, 8); 
    190         // process all ports that should be handled on a per-packet base 
    191         // this is MIDI for AMDTP (due to the need of DBC) 
    192         if(isRunning()) { 
    193             if (!decodePacketPorts((quadlet_t *)(data+8), n_events, dbc)) { 
    194                 debugWarning("Problem decoding Packet Ports\n"); 
    195             } 
    196         } 
    197189        return eCRV_OK; 
    198190    } else { 
     
    211203{ 
    212204    bool no_problem=true; 
    213     for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    214           it != m_PeriodPorts.end(); 
     205    for ( PortVectorIterator it = m_Ports.begin(); 
     206          it != m_Ports.end(); 
    215207          ++it ) { 
    216208        if((*it)->isDisabled()) {continue;}; 
    217209 
    218         //FIXME: make this into a static_cast when not DEBUG? 
    219         Port *port=dynamic_cast<Port *>(*it); 
     210        Port *port=(*it); 
    220211 
    221212        switch(port->getPortType()) { 
     
    227218            } 
    228219            break; 
    229         // midi is a packet based port, don't process 
    230         //    case MotuPortInfo::E_Midi: 
    231         //        break; 
     220        case Port::E_Midi: 
     221//             if(decodeMotuMidiEventsToPort(static_cast<MotuMidiPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
     222//                 debugWarning("Could not decode packet midi data to port %s",(*it)->getName().c_str()); 
     223//                 no_problem=false; 
     224//             } 
     225            break; 
    232226 
    233227        default: // ignore 
     
    236230    } 
    237231    return no_problem; 
    238 } 
    239  
    240 /** 
    241  * @brief decode a packet for the packet-based ports 
    242  * 
    243  * @param data Packet data 
    244  * @param nevents number of events in data (including events of other ports & port types) 
    245  * @param dbc DataBlockCount value for this packet 
    246  * @return true if all successfull 
    247  */ 
    248 bool MotuReceiveStreamProcessor::decodePacketPorts(quadlet_t *data, unsigned int nevents, 
    249         unsigned int dbc) { 
    250     bool ok=true; 
    251  
    252     // Use char here since the source address won't necessarily be 
    253     // aligned; use of an unaligned quadlet_t may cause issues on 
    254     // certain architectures.  Besides, the source for MIDI data going 
    255     // directly to the MOTU isn't structured in quadlets anyway; it is a 
    256     // sequence of 3 unaligned bytes. 
    257     unsigned char *src = NULL; 
    258  
    259     for ( PortVectorIterator it = m_PacketPorts.begin(); 
    260         it != m_PacketPorts.end(); 
    261         ++it ) { 
    262  
    263         Port *port=dynamic_cast<Port *>(*it); 
    264         assert(port); // this should not fail!! 
    265  
    266         // Currently the only packet type of events for MOTU 
    267         // is MIDI in mbla.  However in future control data 
    268         // might also be sent via "packet" events, so allow 
    269         // for this possible expansion. 
    270  
    271         // FIXME: MIDI input is completely untested at present. 
    272         switch (port->getPortType()) { 
    273             case Port::E_Midi: { 
    274                 MotuMidiPort *mp=static_cast<MotuMidiPort *>(*it); 
    275                 signed int sample; 
    276                 unsigned int j = 0; 
    277                 // Get MIDI bytes if present anywhere in the 
    278                 // packet.  MOTU MIDI data is sent using a 
    279                 // 3-byte sequence starting at the port's 
    280                 // position.  It's thought that there can never 
    281                 // be more than one MIDI byte per packet, but 
    282                 // for completeness we'll check the entire packet 
    283                 // anyway. 
    284                 src = (unsigned char *)data + mp->getPosition(); 
    285                 while (j < nevents) { 
    286                     if (*src==0x01 && *(src+1)==0x00) { 
    287                         sample = *(src+2); 
    288                         if (!mp->writeEvent(&sample)) { 
    289                             debugWarning("MIDI packet port events lost\n"); 
    290                             ok = false; 
    291                         } 
    292                     } 
    293                     j++; 
    294                     src += m_event_size; 
    295                 } 
    296                 break; 
    297             } 
    298             default: 
    299                 debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown packet-type port format %d\n",port->getPortType()); 
    300                 return ok; 
    301               } 
    302     } 
    303  
    304     return ok; 
    305232} 
    306233 
     
    319246    src_data = (unsigned char *)data + p->getPosition(); 
    320247 
    321     switch(p->getDataType()) { 
     248    switch(m_StreamProcessorManager.getAudioDataType()) { 
    322249        default: 
    323         case Port::E_Int24: 
     250        case StreamProcessorManager::eADT_Int24: 
    324251            { 
    325252                quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress()); 
     
    347274            } 
    348275            break; 
    349         case Port::E_Float: 
     276        case StreamProcessorManager::eADT_Float: 
    350277            { 
    351278                const float multiplier = 1.0f / (float)(0x7FFFFF); 
  • trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp

    r798 r833  
    6262{} 
    6363 
    64  
    6564unsigned int 
    6665MotuTransmitStreamProcessor::getMaxPacketSize() { 
     
    310309        } 
    311310 
    312         // Process all ports that should be handled on a per-packet base 
    313         // this is MIDI for AMDTP (due to the need of DBC, which is lost 
    314         // when putting the events in the ringbuffer) 
    315         // for motu this might also be control data, however as control 
    316         // data isn't time specific I would also include it in the period 
    317         // based processing 
    318  
    319         // FIXME: m_tx_dbc probably needs to be initialised to a non-zero 
    320         // value somehow so MIDI sync is possible.  For now we ignore 
    321         // this issue. 
    322         if (!encodePacketPorts((quadlet_t *)(data+8), n_events, m_tx_dbc)) { 
    323             debugWarning("Problem encoding Packet Ports\n"); 
    324         } 
    325  
    326311        return eCRV_OK; 
    327312    } 
     
    403388{ 
    404389    debugOutput ( DEBUG_LEVEL_VERBOSE, "Preparing (%p)...\n", this ); 
    405  
    406  
    407 #if 0 
    408     for ( PortVectorIterator it = m_Ports.begin(); 
    409             it != m_Ports.end(); 
    410             ++it ) 
    411     { 
    412         if ( ( *it )->getPortType() == Port::E_Midi ) 
    413         { 
    414             // we use a timing unit of 10ns 
    415             // this makes sure that for the max syt interval 
    416             // we don't have rounding, and keeps the numbers low 
    417             // we have 1 slot every 8 events 
    418             // we have syt_interval events per packet 
    419             // => syt_interval/8 slots per packet 
    420             // packet rate is 8000pkt/sec => interval=125us 
    421             // so the slot interval is (1/8000)/(syt_interval/8) 
    422             // or: 1/(1000 * syt_interval) sec 
    423             // which is 1e9/(1000*syt_interval) nsec 
    424             // or 100000/syt_interval 'units' 
    425             // the event interval is fixed to 320us = 32000 'units' 
    426             if ( ! ( *it )->useRateControl ( true, ( 100000/m_syt_interval ),32000, false ) ) 
    427             { 
    428                 debugFatal ( "Could not set signal type to PeriodSignalling" ); 
    429                 return false; 
    430             } 
    431             break; 
    432         } 
    433     } 
    434 #endif 
    435390    return true; 
    436391} 
     
    450405    } 
    451406 
    452     for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    453       it != m_PeriodPorts.end(); 
     407    for ( PortVectorIterator it = m_Ports.begin(); 
     408      it != m_Ports.end(); 
    454409      ++it ) { 
    455410        // If this port is disabled, don't process it 
    456411        if((*it)->isDisabled()) {continue;}; 
    457412 
    458         //FIXME: make this into a static_cast when not DEBUG? 
    459         Port *port=dynamic_cast<Port *>(*it); 
     413        Port *port=(*it); 
    460414 
    461415        switch(port->getPortType()) { 
     
    463417        case Port::E_Audio: 
    464418            if (encodePortToMotuEvents(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
    465                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str()); 
     419                debugWarning("Could not encode port %s to Motu events",(*it)->getName().c_str()); 
    466420                no_problem=false; 
    467421            } 
    468422            break; 
    469         // midi is a packet based port, don't process 
    470         //    case MotuPortInfo::E_Midi: 
    471         //        break; 
    472  
     423        case Port::E_Midi: 
     424//             if (encodePortToMotuMidiEvents(static_cast<MotuMidiPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
     425//                 debugWarning("Could not encode port %s to Midi events",(*it)->getName().c_str()); 
     426//                 no_problem=false; 
     427//             } 
     428            break; 
    473429        default: // ignore 
    474430            break; 
     
    484440    // doesn't read from the port buffers. 
    485441    bool no_problem = true; 
    486     for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    487       it != m_PeriodPorts.end(); 
     442    for ( PortVectorIterator it = m_Ports.begin(); 
     443      it != m_Ports.end(); 
    488444      ++it ) { 
    489         //FIXME: make this into a static_cast when not DEBUG? 
    490         Port *port=dynamic_cast<Port *>(*it); 
     445        Port *port=(*it); 
    491446 
    492447        switch(port->getPortType()) { 
     
    498453            } 
    499454            break; 
    500         // midi is a packet based port, don't process 
    501         //    case MotuPortInfo::E_Midi: 
    502         //        break; 
    503  
     455        case Port::E_Midi: 
     456//             if (encodeSilencePortToMotuMidiEvents(static_cast<MotuMidiPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
     457//                 debugWarning("Could not encode port %s to Midi events",(*it)->getName().c_str()); 
     458//                 no_problem = false; 
     459//             } 
     460            break; 
    504461        default: // ignore 
    505462            break; 
     
    507464    } 
    508465    return no_problem; 
    509 } 
    510  
    511 /** 
    512  * @brief encode a packet for the packet-based ports 
    513  * 
    514  * @param data Packet data 
    515  * @param nevents number of events in data (including events of other ports & port types) 
    516  * @param dbc DataBlockCount value for this packet 
    517  * @return true if all successfull 
    518  */ 
    519 bool MotuTransmitStreamProcessor::encodePacketPorts(quadlet_t *data, unsigned int nevents, 
    520         unsigned int dbc) { 
    521     bool ok=true; 
    522     char byte; 
    523  
    524     // Use char here since the target address won't necessarily be 
    525     // aligned; use of an unaligned quadlet_t may cause issues on 
    526     // certain architectures.  Besides, the target for MIDI data going 
    527     // directly to the MOTU isn't structured in quadlets anyway; it is a 
    528     // sequence of 3 unaligned bytes. 
    529     unsigned char *target = NULL; 
    530  
    531     for ( PortVectorIterator it = m_PacketPorts.begin(); 
    532         it != m_PacketPorts.end(); 
    533         ++it ) { 
    534  
    535         Port *port=static_cast<Port *>(*it); 
    536          assert(port); // this should not fail!! 
    537  
    538         // Currently the only packet type of events for MOTU 
    539         // is MIDI in mbla.  However in future control data 
    540         // might also be sent via "packet" events. 
    541         // assert(pinfo->getFormat()==MotuPortInfo::E_Midi); 
    542  
    543         // FIXME: MIDI output is completely untested at present. 
    544         switch (port->getPortType()) { 
    545             case Port::E_Midi: { 
    546                 MotuMidiPort *mp=static_cast<MotuMidiPort *>(*it); 
    547  
    548                 // Send a byte if we can. MOTU MIDI data is 
    549                 // sent using a 3-byte sequence starting at 
    550                 // the port's position.  For now we'll 
    551                 // always send in the first event of a 
    552                 // packet, but this might need refinement 
    553                 // later. 
    554                 if (mp->canRead()) { 
    555                     mp->readEvent(&byte); 
    556                     target = (unsigned char *)data + mp->getPosition(); 
    557                     *(target++) = 0x01; 
    558                     *(target++) = 0x00; 
    559                     *(target++) = byte; 
    560                 } 
    561                 break; 
    562             } 
    563             default: 
    564                 debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown packet-type port type %d\n",port->getPortType()); 
    565                 return ok; 
    566               } 
    567     } 
    568  
    569     return ok; 
    570466} 
    571467 
     
    596492    target = (unsigned char *)data + p->getPosition(); 
    597493 
    598     switch(p->getDataType()) { 
     494    switch(m_StreamProcessorManager.getAudioDataType()) { 
    599495        default: 
    600         case Port::E_Int24: 
     496        case StreamProcessorManager::eADT_Int24: 
    601497            { 
    602498                quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress()); 
     
    620516            } 
    621517            break; 
    622         case Port::E_Float: 
     518        case StreamProcessorManager::eADT_Float: 
    623519            { 
    624520                const float multiplier = (float)(0x7FFFFF); 
     
    650546    unsigned char *target = (unsigned char *)data + p->getPosition(); 
    651547 
    652     switch (p->getDataType()) { 
     548    switch (m_StreamProcessorManager.getAudioDataType()) { 
    653549    default: 
    654         case Port::E_Int24: 
    655         case Port::E_Float: 
     550        case StreamProcessorManager::eADT_Int24: 
     551        case StreamProcessorManager::eADT_Float: 
    656552        for (j = 0; j < nevents; j++) { 
    657553            *target = *(target+1) = *(target+2) = 0; 
  • trunk/libffado/src/libstreaming/StreamProcessorManager.cpp

    r807 r833  
    4141    : m_is_slave( false ) 
    4242    , m_SyncSource(NULL) 
     43    , m_xrun_happened( false ) 
    4344    , m_nb_buffers( 0 ) 
    4445    , m_period( 0 ) 
     46    , m_audio_datatype( eADT_Float ) 
    4547    , m_nominal_framerate ( 0 ) 
    46     , m_xrun_happened( false ) 
    4748    , m_xruns(0) 
    4849    , m_nbperiods(0) 
     
    5455    : m_is_slave( false ) 
    5556    , m_SyncSource(NULL) 
     57    , m_xrun_happened( false ) 
    5658    , m_nb_buffers(nb_buffers) 
    5759    , m_period(period) 
     60    , m_audio_datatype( eADT_Float ) 
    5861    , m_nominal_framerate ( framerate ) 
    5962    , m_xruns(0) 
    60     , m_xrun_happened( false ) 
    6163    , m_nbperiods(0) 
    6264{ 
     
    220222    debugOutput( DEBUG_LEVEL_VERBOSE, "Putting StreamProcessor streams into dry-running state...\n"); 
    221223    debugOutput( DEBUG_LEVEL_VERBOSE, " Schedule start dry-running...\n"); 
    222     for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    223             it != m_ReceiveProcessors.end(); 
     224    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     225            it != m_TransmitProcessors.end(); 
    224226            ++it ) { 
    225227        if (!(*it)->isDryRunning()) { 
     
    232234        } 
    233235    } 
    234     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    235             it != m_TransmitProcessors.end(); 
     236    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     237            it != m_ReceiveProcessors.end(); 
    236238            ++it ) { 
    237239        if (!(*it)->isDryRunning()) { 
     
    324326    // DLL to have a decent sync (FIXME: does the DLL get updated when dry-running)? 
    325327    debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for sync...\n"); 
    326     int nb_sync_runs=20; 
     328     
     329    unsigned int nb_sync_runs = (STREAMPROCESSORMANAGER_SYNC_WAIT_TIME_MSEC * getNominalRate()); 
     330    nb_sync_runs /= 1000; 
     331    nb_sync_runs /= getPeriodSize(); 
     332 
    327333    int64_t time_till_next_period; 
    328334    while(nb_sync_runs--) { // or while not sync-ed? 
     
    417423    } 
    418424 
    419     // now align the received streams 
    420425    if(!alignReceivedStreams()) { 
    421         debugError("Could not align streams\n"); 
     426        debugError("Could not align streams...\n"); 
    422427        return false; 
    423428    } 
     429 
    424430    debugOutput( DEBUG_LEVEL_VERBOSE, " StreamProcessor streams running...\n"); 
    425431    return true; 
     
    429435StreamProcessorManager::alignReceivedStreams() 
    430436{ 
    431     if(m_SyncSource == NULL) return false; 
    432437    debugOutput( DEBUG_LEVEL_VERBOSE, "Aligning received streams...\n"); 
    433438    unsigned int nb_sync_runs; 
     
    506511    debugOutput( DEBUG_LEVEL_VERBOSE, "Starting Processors...\n"); 
    507512 
    508     // put all SP's into dry-running state 
    509     if (!startDryRunning()) { 
    510         debugFatal("Could not put SP's in dry-running state\n"); 
    511         return false; 
    512     } 
    513  
    514513    // start all SP's synchonized 
    515     if (!syncStartAll()) { 
     514    bool start_result = false; 
     515    for (int ntries; ntries < STREAMPROCESSORMANAGER_SYNCSTART_TRIES; ntries++) { 
     516        // put all SP's into dry-running state 
     517        if (!startDryRunning()) { 
     518            debugOutput(DEBUG_LEVEL_VERBOSE, "Could not put SP's in dry-running state (try %d)\n", ntries); 
     519            start_result = false; 
     520            continue; 
     521        } 
     522 
     523        start_result = syncStartAll(); 
     524        if(start_result) { 
     525            break; 
     526        } else { 
     527            debugOutput(DEBUG_LEVEL_VERBOSE, "Sync start try %d failed...\n", ntries); 
     528        } 
     529    } 
     530    if (!start_result) { 
    516531        debugFatal("Could not syncStartAll...\n"); 
    517532        return false; 
    518533    } 
     534 
    519535    return true; 
    520536} 
     
    643659     */ 
    644660 
    645     // put all SP's back into dry-running state 
    646     if (!startDryRunning()) { 
    647         debugFatal("Could not put SP's in dry-running state\n"); 
    648         return false; 
    649     } 
    650  
    651661    debugOutput( DEBUG_LEVEL_VERBOSE, "Restarting StreamProcessors...\n"); 
    652662    // start all SP's synchonized 
    653     if (!syncStartAll()) { 
     663    bool start_result = false; 
     664    for (int ntries; ntries < STREAMPROCESSORMANAGER_SYNCSTART_TRIES; ntries++) { 
     665        // put all SP's into dry-running state 
     666        if (!startDryRunning()) { 
     667            debugShowBackLog(); 
     668            debugOutput(DEBUG_LEVEL_VERBOSE, "Could not put SP's in dry-running state (try %d)\n", ntries); 
     669            start_result = false; 
     670            continue; 
     671        } 
     672 
     673        start_result = syncStartAll(); 
     674        if(start_result) { 
     675            break; 
     676        } else { 
     677            debugOutput(DEBUG_LEVEL_VERBOSE, "Sync start try %d failed...\n", ntries); 
     678        } 
     679    } 
     680    if (!start_result) { 
    654681        debugFatal("Could not syncStartAll...\n"); 
    655682        return false; 
    656683    } 
    657  
    658684    debugOutput( DEBUG_LEVEL_VERBOSE, "Xrun handled...\n"); 
    659685 
     
    675701 
    676702    while(period_not_ready) { 
    677         debugOutput( DEBUG_LEVEL_VERBOSE, "waiting for period (%d frames in buffer)...\n", m_SyncSource->getBufferFill()); 
     703        debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "waiting for period (%d frames in buffer)...\n", m_SyncSource->getBufferFill()); 
    678704        if(!m_SyncSource->waitForSignal()) { 
    679705            debugError("Error waiting for signal\n"); 
     
    686712#ifdef DEBUG 
    687713        if(period_not_ready) { 
    688             debugOutput(DEBUG_LEVEL_VERBOSE, "period is not ready (bufferfill: %u)\n", bufferfill); 
     714            debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "period is not ready (bufferfill: %u)\n", bufferfill); 
    689715        } else { 
    690             debugOutput(DEBUG_LEVEL_VERBOSE, "period is ready (bufferfill: %u)\n", bufferfill); 
     716            debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "period is ready (bufferfill: %u)\n", bufferfill); 
    691717        } 
    692718#endif 
     
    717743    //       and the receive processors should have done their transfer. 
    718744    m_time_of_transfer = m_SyncSource->getTimeAtPeriod(); 
    719     debugOutput( DEBUG_LEVEL_VERBOSE, "transfer at %llu ticks...\n", 
     745    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "transfer at %llu ticks...\n", 
    720746        m_time_of_transfer); 
    721747 
     
    915941    debugOutputShort( DEBUG_LEVEL_NORMAL, "Dumping StreamProcessorManager information...\n"); 
    916942    debugOutputShort( DEBUG_LEVEL_NORMAL, "Period count: %6d\n", m_nbperiods); 
     943    debugOutputShort( DEBUG_LEVEL_NORMAL, "Data type: %s\n", (m_audio_datatype==eADT_Float?"float":"int24")); 
    917944 
    918945    debugOutputShort( DEBUG_LEVEL_NORMAL, " Receive processors...\n"); 
  • trunk/libffado/src/libstreaming/StreamProcessorManager.h

    r750 r833  
    5050 
    5151public: 
     52    enum eADT_AudioDataType { 
     53        eADT_Int24, 
     54        eADT_Float, 
     55    }; 
    5256 
    5357    StreamProcessorManager(); 
     
    7175    unsigned int getPeriodSize() 
    7276            {return m_period;}; 
     77 
     78    bool setAudioDataType(enum eADT_AudioDataType t) 
     79        {m_audio_datatype = t; return true;}; 
     80    enum eADT_AudioDataType getAudioDataType() 
     81        {return m_audio_datatype;} 
    7382 
    7483    void setNbBuffers(unsigned int nb_buffers) 
     
    139148    unsigned int m_nb_buffers; 
    140149    unsigned int m_period; 
     150    enum eADT_AudioDataType m_audio_datatype; 
    141151    unsigned int m_nominal_framerate; 
    142152    unsigned int m_xruns; 
  • trunk/libffado/src/libutil/TimestampedBuffer.cpp

    r807 r833  
    3838#define DLL_COEFF_C   (DLL_OMEGA * DLL_OMEGA) 
    3939 
     40#define FRAMES_PER_PROCESS_BLOCK 8 
    4041/* 
    4142#define ENTER_CRITICAL_SECTION { \ 
     
    5859 
    5960TimestampedBuffer::TimestampedBuffer(TimestampedBufferClient *c) 
    60     : m_event_buffer(NULL), m_cluster_buffer(NULL), 
     61    : m_event_buffer(NULL), m_process_buffer(NULL), m_cluster_size( 0 ), 
     62      m_process_block_size( 0 ), 
    6163      m_event_size(0), m_events_per_frame(0), m_buffer_size(0), 
    6264      m_bytes_per_frame(0), m_bytes_per_buffer(0), 
     
    7577TimestampedBuffer::~TimestampedBuffer() { 
    7678    ffado_ringbuffer_free(m_event_buffer); 
    77     free(m_cluster_buffer); 
     79    free(m_process_buffer); 
    7880} 
    7981 
     
    278280 
    279281/** 
    280  * \brief Initializes the TimestampedBuffer 
    281  * 
    282  * Initializes the TimestampedBuffer, should be called before anything else 
    283  * is done. 
    284  * 
    285  * @return true if successful 
    286  */ 
    287 bool TimestampedBuffer::init() { 
    288     return true; 
    289 } 
    290  
    291 /** 
    292282 * \brief Resets the TimestampedBuffer 
    293283 * 
     
    346336 
    347337    // allocate the temporary cluster buffer 
    348     if( !(m_cluster_buffer=(char *)calloc(m_events_per_frame,m_event_size))) { 
     338    // NOTE: has to be a multiple of 8 in order to 
     339    //       correctly decode midi bytes (since that  
     340    //       enforces packet alignment) 
     341    m_cluster_size = m_events_per_frame * m_event_size; 
     342    m_process_block_size = m_cluster_size * FRAMES_PER_PROCESS_BLOCK; 
     343    if( !(m_process_buffer=(char *)calloc(m_process_block_size, 1))) { 
    349344            debugFatal("Could not allocate temporary cluster buffer\n"); 
    350345        ffado_ringbuffer_free(m_event_buffer); 
     
    535530    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n"); 
    536531    int xrun; 
    537     unsigned int offset=0; 
     532    unsigned int offset = 0; 
    538533 
    539534    ffado_ringbuffer_data_t vec[2]; 
    540535    // we received one period of frames 
    541536    // this is period_size*dimension of events 
    542     unsigned int events2write=nbframes*m_events_per_frame; 
    543     unsigned int bytes2write=events2write*m_event_size; 
     537    unsigned int events2write = nbframes * m_events_per_frame; 
     538    unsigned int bytes2write = events2write * m_event_size; 
    544539 
    545540    /* write events2write bytes to the ringbuffer 
     
    551546    *  Make sure that we cannot end up on a non-cluster aligned position! 
    552547    */ 
    553     unsigned int cluster_size=m_events_per_frame*m_event_size; 
    554  
    555     while(bytes2write>0) { 
    556         int byteswritten=0; 
    557  
    558         unsigned int frameswritten=(nbframes*cluster_size-bytes2write)/cluster_size; 
    559         offset=frameswritten; 
     548 
     549    while(bytes2write > 0) { 
     550        int byteswritten = 0; 
     551 
     552        unsigned int frameswritten = (nbframes * m_cluster_size - bytes2write) / m_cluster_size; 
     553        offset = frameswritten; 
    560554 
    561555        ffado_ringbuffer_get_write_vector(m_event_buffer, vec); 
    562556 
    563         if(vec[0].len==0) { // this indicates a full event buffer 
     557        if(vec[0].len + vec[1].len < m_process_block_size) { // this indicates a full event buffer 
    564558            debugError("Event buffer overrun in buffer %p, fill: %u, bytes2write: %u \n", 
    565559                       this, ffado_ringbuffer_read_space(m_event_buffer), bytes2write); 
     
    574568        * this can happen because the ringbuffer size is always a power of 2 
    575569        */ 
    576         if(vec[0].len<cluster_size) { 
     570        if(vec[0].len < m_process_block_size) { 
    577571 
    578572            // encode to the temporary buffer 
    579             xrun = m_Client->processWriteBlock(m_cluster_buffer, 1, offset); 
    580  
    581             if(xrun<0) { 
     573            // note that we always process 8 frames at once, in order to ensure that 
     574            // we don't have to care about the DBC field 
     575            xrun = m_Client->processWriteBlock(m_process_buffer, FRAMES_PER_PROCESS_BLOCK, offset); 
     576 
     577            if(xrun < 0) { 
    582578                // xrun detected 
    583579                debugError("Frame buffer underrun in buffer %p\n",this); 
     
    588584            // the write function handles the wrap around. 
    589585            ffado_ringbuffer_write(m_event_buffer, 
    590                          m_cluster_buffer, 
    591                          cluster_size); 
     586                                   m_process_buffer, 
     587                                   m_process_block_size); 
    592588 
    593589            // we advanced one cluster_size 
    594             bytes2write-=cluster_size; 
     590            bytes2write -= m_process_block_size; 
    595591 
    596592        } else { // 
    597593 
    598             if(bytes2write>vec[0].len) { 
     594            if(bytes2write > vec[0].len) { 
    599595                // align to a cluster boundary 
    600                 byteswritten=vec[0].len-(vec[0].len%cluster_size); 
     596                byteswritten = vec[0].len - (vec[0].len % m_process_block_size); 
    601597            } else { 
    602                 byteswritten=bytes2write; 
     598                byteswritten = bytes2write; 
    603599            } 
    604600 
    605601            xrun = m_Client->processWriteBlock(vec[0].buf, 
    606                          byteswritten/cluster_size, 
    607                          offset); 
    608  
    609             if(xrun<0) { 
    610                     // xrun detected 
     602                                               byteswritten / m_cluster_size, 
     603                                               offset); 
     604 
     605            if(xrun < 0 ) { 
     606                // xrun detected 
    611607                debugError("Frame buffer underrun in buffer %p\n",this); 
    612608                return false; // FIXME: return false ? 
     
    617613        } 
    618614 
    619         // the bytes2write should always be cluster aligned 
    620         assert(bytes2write%cluster_size==0); 
     615        // the bytes2write should always be process block aligned 
     616        assert(bytes2write % m_process_block_size == 0); 
    621617 
    622618    } 
     
    644640 
    645641    int xrun; 
    646     unsigned int offset=0; 
     642    unsigned int offset = 0; 
    647643 
    648644    ffado_ringbuffer_data_t vec[2]; 
     
    650646    // this is period_size*dimension of events 
    651647 
    652     unsigned int events2read=nbframes*m_events_per_frame; 
    653     unsigned int bytes2read=events2read*m_event_size; 
     648    unsigned int events2read = nbframes * m_events_per_frame; 
     649    unsigned int bytes2read = events2read * m_event_size; 
    654650    /* read events2read bytes from the ringbuffer 
    655651    *  first see if it can be done in one read. 
     
    660656    *  Make sure that we cannot end up on a non-cluster aligned position! 
    661657    */ 
    662     unsigned int cluster_size=m_events_per_frame*m_event_size; 
    663  
    664     while(bytes2read>0) { 
    665         unsigned int framesread=(nbframes*cluster_size-bytes2read)/cluster_size; 
    666         offset=framesread; 
    667  
    668         int bytesread=0; 
     658 
     659    while(bytes2read > 0) { 
     660        unsigned int framesread = (nbframes * m_cluster_size - bytes2read) / m_cluster_size; 
     661        offset = framesread; 
     662 
     663        int bytesread = 0; 
    669664 
    670665        ffado_ringbuffer_get_read_vector(m_event_buffer, vec); 
    671666 
    672         if(vec[0].len==0) { // this indicates an empty event buffer 
     667        if(vec[0].len + vec[1].len < m_process_block_size) { // this indicates an empty event buffer 
    673668            debugError("Event buffer underrun in buffer %p\n",this); 
    674669            return false; 
     
    680675        * this can happen because the ringbuffer size is always a power of 2 
    681676                */ 
    682         if(vec[0].len<cluster_size) { 
     677        if(vec[0].len < m_process_block_size) { 
    683678            // use the ringbuffer function to read one cluster 
    684679            // the read function handles wrap around 
    685             ffado_ringbuffer_read(m_event_buffer,m_cluster_buffer,cluster_size); 
     680            ffado_ringbuffer_read(m_event_buffer, m_process_buffer, m_process_block_size); 
    686681 
    687682            assert(m_Client); 
    688             xrun = m_Client->processReadBlock(m_cluster_buffer, 1, offset); 
    689  
    690             if(xrun<0) { 
     683            // note that we always process 8 frames at once, in order to ensure that 
     684            // we don't have to care about the DBC field 
     685            xrun = m_Client->processReadBlock(m_process_buffer, FRAMES_PER_PROCESS_BLOCK, offset); 
     686 
     687            if(xrun < 0) { 
    691688                // xrun detected 
    692689                debugError("Frame buffer overrun in buffer %p\n",this); 
     
    695692 
    696693            // we advanced one cluster_size 
    697             bytes2read-=cluster_size; 
     694            bytes2read -= m_process_block_size; 
    698695 
    699696        } else { // 
    700697 
    701             if(bytes2read>vec[0].len) { 
     698            if(bytes2read > vec[0].len) { 
    702699                // align to a cluster boundary 
    703                 bytesread=vec[0].len-(vec[0].len%cluster_size); 
     700                bytesread = vec[0].len - (vec[0].len % m_process_block_size); 
    704701            } else { 
    705                 bytesread=bytes2read; 
     702                bytesread = bytes2read; 
    706703            } 
    707704 
    708705            assert(m_Client); 
    709             xrun = m_Client->processReadBlock(vec[0].buf, bytesread/cluster_size, offset); 
    710  
    711             if(xrun<0) { 
     706            xrun = m_Client->processReadBlock(vec[0].buf, bytesread/m_cluster_size, offset); 
     707 
     708            if(xrun < 0) { 
    712709                // xrun detected 
    713710                debugError("Frame buffer overrun in buffer %p\n",this); 
     
    720717 
    721718        // the bytes2read should always be cluster aligned 
    722         assert(bytes2read%cluster_size==0); 
     719        assert(bytes2read % m_process_block_size == 0); 
    723720    } 
    724721 
     
    11771174 
    11781175    if (diff > max_abs_diff) { 
    1179         debugShowBackLogLines(100); 
     1176//         debugShowBackLogLines(100); 
    11801177        debugWarning("(%p) difference rather large (+): diff="TIMESTAMP_FORMAT_SPEC", max="TIMESTAMP_FORMAT_SPEC", "TIMESTAMP_FORMAT_SPEC", "TIMESTAMP_FORMAT_SPEC"\n", 
    11811178            this, diff, max_abs_diff, ts, pred_buffer_next_tail_timestamp); 
    11821179    } else if (diff < -max_abs_diff) { 
    1183         debugShowBackLogLines(100); 
     1180//         debugShowBackLogLines(100); 
    11841181        debugWarning("(%p) difference rather large (-): diff="TIMESTAMP_FORMAT_SPEC", max="TIMESTAMP_FORMAT_SPEC", "TIMESTAMP_FORMAT_SPEC", "TIMESTAMP_FORMAT_SPEC"\n", 
    11851182            this, diff, -max_abs_diff, ts, pred_buffer_next_tail_timestamp); 
  • trunk/libffado/src/libutil/TimestampedBuffer.h

    r807 r833  
    8989        virtual ~TimestampedBuffer(); 
    9090 
    91         /** 
    92          * @brief waits for the availability of frames (blocking) 
    93          * @param nframes number of frames 
    94          * 
    95          * @return true if frames are available, false if not (e.g. signal occurred) 
    96          */ 
    97         bool waitForFrames(unsigned int nframes); 
    98  
    99         /** 
    100          * @brief waits for the availability of frames (blocking) 
    101          * 
    102          * waits for one update period of frames 
    103          * 
    104          * @return true if frames are available, false if not (e.g. signal occurred) 
    105          */ 
    106         bool waitForFrames(); 
    107  
    108         /** 
    109          * @brief waits for the availability of frames (non-blocking) 
    110          * @param nframes number of frames 
    111          * 
    112          * @return true if frames are available, false if not 
    113          */ 
    114         bool tryWaitForFrames(unsigned int nframes); 
    115  
    116         /** 
    117          * @brief waits for the availability of frames (non-blocking) 
    118          * 
    119          * waits for one update period of frames 
    120          * 
    121          * @return true if frames are available, false if not 
    122          */ 
    123         bool tryWaitForFrames(); 
    124  
    12591        bool writeDummyFrame(); 
    12692        bool dropFrames ( unsigned int nbframes ); 
     
    134100        bool blockProcessReadFrames ( unsigned int nbframes ); 
    135101 
    136         bool init(); 
    137102        bool prepare(); 
    138103        bool clearBuffer(); 
     
    201166 
    202167        ffado_ringbuffer_t * m_event_buffer; 
    203         char* m_cluster_buffer; 
     168        char* m_process_buffer; 
     169        unsigned int m_cluster_size; 
     170        unsigned int m_process_block_size; 
    204171 
    205172        unsigned int m_event_size; // the size of one event 
  • trunk/libffado/src/motu/motu_avdevice.cpp

    r785 r833  
    554554    // event data. 
    555555    asprintf(&buff,"%s_cap_MIDI0",id.c_str()); 
    556     p = new Streaming::MotuMidiPort(buff, 
     556    p = new Streaming::MotuMidiPort(*m_receiveProcessor, buff, 
    557557        Streaming::Port::E_Capture, 4); 
    558558    if (!p) { 
    559559        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n", buff); 
    560     } else { 
    561         if (!m_receiveProcessor->addPort(p)) { 
    562             debugWarning("Could not register port with stream processor\n"); 
    563             free(buff); 
    564             return false; 
    565         } else { 
    566             debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n", buff); 
    567         } 
    568560    } 
    569561    free(buff); 
     
    613605    // of the event data. 
    614606    asprintf(&buff,"%s_pbk_MIDI0",id.c_str()); 
    615     p = new Streaming::MotuMidiPort(buff, 
     607    p = new Streaming::MotuMidiPort(*m_transmitProcessor, buff, 
    616608        Streaming::Port::E_Capture, 4); 
    617609    if (!p) { 
    618610        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n", buff); 
    619     } else { 
    620         if (!m_receiveProcessor->addPort(p)) { 
    621             debugWarning("Could not register port with stream processor\n"); 
    622             free(buff); 
    623             return false; 
    624         } else { 
    625             debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n", buff); 
    626         } 
    627611    } 
    628612    free(buff); 
     
    862846Streaming::Port *p=NULL; 
    863847 
    864     p = new Streaming::MotuAudioPort(name, direction, position, size); 
     848    p = new Streaming::MotuAudioPort(*s_processor, name, direction, position, size); 
    865849 
    866850    if (!p) { 
    867851        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",name); 
    868     } else { 
    869         if (!s_processor->addPort(p)) { 
    870             debugWarning("Could not register port with stream processor\n"); 
    871             free(name); 
    872             return false; 
    873         } else { 
    874             debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",name); 
    875         } 
    876         p->enable(); 
    877852    } 
    878853    free(name); 
  • trunk/libffado/tests/streaming/SConscript

    r792 r833  
    3030env.PrependUnique( LIBS=["ffado"] ) 
    3131 
    32 apps = "teststreaming teststreaming2" 
    33 if env.GetOption('clean') or env['ALSA_SEQ_OUTPUT']: 
    34         apps += " testmidistreaming1" 
    35  
    36 for app in env.Split( apps ): 
    37         env.Program( target=app, source = [ app+".c", "debugtools.c" ] ) 
    38  
    3932cppapps = "teststreaming3" 
    4033 
  • trunk/libffado/tests/streaming/teststreaming3.cpp

    r807 r833  
    6767    long int sample_rate; 
    6868    long int rtprio; 
     69    long int audio_buffer_type; 
    6970    char* args[2]; 
    7071     
     
    8283    {"slave_mode",  's', "bool",  0,  "Run in slave mode" }, 
    8384    {"snoop_mode",  'S', "bool",  0,  "Run in snoop mode" }, 
     85    {"audio_buffer_type",  'b', "",  0,  "Datatype of audio buffers (0=float, 1=int24)" }, 
    8486    { 0 } 
    8587}; 
     
    156158            if ( errno ) { 
    157159                fprintf( stderr,  "Could not parse 'test-tone-freq' argument\n" ); 
     160                return ARGP_ERR_UNKNOWN; 
     161            } 
     162        } 
     163        break; 
     164    case 'b': 
     165        if (arg) { 
     166            arguments->audio_buffer_type = strtol( arg, &tail, 0 ); 
     167            if ( errno ) { 
     168                fprintf( stderr,  "Could not parse 'audio-buffer-type' argument\n" ); 
    158169                return ARGP_ERR_UNKNOWN; 
    159170            } 
     
    225236{ 
    226237    run = 0; 
    227     set_realtime_priority(0); 
    228238} 
    229239 
     
    243253    arguments.sample_rate       = 44100; 
    244254    arguments.rtprio            = 0; 
     255    arguments.audio_buffer_type = 0; 
    245256     
    246257    // Parse our arguments; every option seen by `parse_opt' will 
     
    254265    setDebugLevel(arguments.verbose); 
    255266 
    256     int samplesread=0; 
    257 //     int sampleswritten=0; 
    258267    int nb_in_channels=0, nb_out_channels=0; 
    259     int retval=0; 
    260268    int i=0; 
    261269    int start_flag = 0; 
     
    307315        exit(-1); 
    308316    } 
     317    if (arguments.audio_buffer_type == 0) { 
     318        ffado_streaming_set_audio_datatype(dev, ffado_audio_datatype_float); 
     319    } else { 
     320        ffado_streaming_set_audio_datatype(dev, ffado_audio_datatype_int24); 
     321    } 
    309322 
    310323    nb_in_channels = ffado_streaming_get_nb_capture_streams(dev); 
     
    316329        min_ch_count = nb_out_channels; 
    317330    } 
    318      
     331 
    319332    /* allocate intermediate buffers */ 
    320333    audiobuffers_in = (float **)calloc(nb_in_channels, sizeof(float *)); 
    321334    for (i=0; i < nb_in_channels; i++) { 
    322335        audiobuffers_in[i] = (float *)calloc(arguments.period+1, sizeof(float)); 
    323              
     336 
    324337        switch (ffado_streaming_get_capture_stream_type(dev,i)) { 
    325338            case ffado_stream_type_audio: 
    326339                /* assign the audiobuffer to the stream */ 
    327340                ffado_streaming_set_capture_stream_buffer(dev, i, (char *)(audiobuffers_in[i])); 
    328                 ffado_streaming_set_capture_buffer_type(dev, i, ffado_buffer_type_float); 
    329341                ffado_streaming_capture_stream_onoff(dev, i, 1); 
    330342                break; 
    331343                // this is done with read/write routines because the nb of bytes can differ. 
    332344            case ffado_stream_type_midi: 
     345                // note that using a float * buffer for midievents is a HACK 
     346                ffado_streaming_set_capture_stream_buffer(dev, i, (char *)(audiobuffers_in[i])); 
     347                ffado_streaming_capture_stream_onoff(dev, i, 1); 
    333348            default: 
    334349                break; 
    335350        } 
    336351    } 
    337      
     352 
    338353    audiobuffers_out = (float **)calloc(nb_out_channels, sizeof(float)); 
    339354    for (i=0; i < nb_out_channels; i++) { 
    340355        audiobuffers_out[i] = (float *)calloc(arguments.period+1, sizeof(float)); 
    341              
     356 
    342357        switch (ffado_streaming_get_playback_stream_type(dev,i)) { 
    343358            case ffado_stream_type_audio: 
    344359                /* assign the audiobuffer to the stream */ 
    345360                ffado_streaming_set_playback_stream_buffer(dev, i, (char *)(audiobuffers_out[i])); 
    346                 ffado_streaming_set_playback_buffer_type(dev, i, ffado_buffer_type_float); 
    347361                ffado_streaming_playback_stream_onoff(dev, i, 1); 
    348362                break; 
    349363                // this is done with read/write routines because the nb of bytes can differ. 
    350364            case ffado_stream_type_midi: 
     365                ffado_streaming_set_playback_stream_buffer(dev, i, (char *)(audiobuffers_out[i])); 
     366                ffado_streaming_playback_stream_onoff(dev, i, 1); 
    351367            default: 
    352368                break; 
     
    385401 
    386402    // start the streaming layer 
    387     ffado_streaming_prepare(dev); 
     403    if (ffado_streaming_prepare(dev)) { 
     404        debugFatal("Could not prepare streaming system\n"); 
     405        ffado_streaming_finish(dev); 
     406        return -1; 
     407    } 
    388408    start_flag = ffado_streaming_start(dev); 
    389409     
     
    391411    debugOutput(DEBUG_LEVEL_NORMAL, "Entering receive loop (IN: %d, OUT: %d)\n", nb_in_channels, nb_out_channels); 
    392412    while(run && start_flag==0) { 
    393         retval = ffado_streaming_wait(dev); 
    394         if (retval < 0) { 
     413        ffado_wait_response response; 
     414        response = ffado_streaming_wait(dev); 
     415        if (response == ffado_wait_xrun) { 
    395416            debugOutput(DEBUG_LEVEL_NORMAL, "Xrun\n"); 
    396417            ffado_streaming_reset(dev); 
    397418            continue; 
    398         } 
    399          
     419        } else if (response == ffado_wait_error) { 
     420            debugError("fatal xrun\n"); 
     421            break; 
     422        } 
    400423        ffado_streaming_transfer_capture_buffers(dev); 
    401          
     424 
    402425        if (arguments.test_tone) { 
    403426            // generate the test tone 
    404427            for (i=0; i<arguments.period; i++) { 
    405                 nullbuffer[i] = amplitude * sin(sine_advance * (frame_counter + (float)i)); 
     428                float v = amplitude * sin(sine_advance * (frame_counter + (float)i)); 
     429                if (arguments.audio_buffer_type == 0) { 
     430                    nullbuffer[i] = v; 
     431                } else { 
     432                    v = (v * 2147483392.0); 
     433                    int32_t tmp = ((int) v); 
     434                    tmp = tmp >> 8; 
     435                    memcpy(&nullbuffer[i], &tmp, sizeof(float)); 
     436                } 
    406437            } 
    407438             
     
    413444            } 
    414445        } else { 
     446            uint32_t *midibuffer; 
     447            int idx; 
    415448            for (i=0; i < min_ch_count; i++) { 
    416449                switch (ffado_streaming_get_capture_stream_type(dev,i)) { 
     
    423456                        // this is done with read/write routines because the nb of bytes can differ. 
    424457                    case ffado_stream_type_midi: 
     458                        midibuffer=(uint32_t *)audiobuffers_in[i]; 
     459                        for(idx=0; idx < arguments.period; idx++) { 
     460                            uint32_t midievent = *(midibuffer + idx); 
     461                            if(midievent & 0xFF000000) { 
     462                                debugOutput(DEBUG_LEVEL_NORMAL, " Received midi event %08X at idx %d of period %d on port %d\n",  
     463                                            midievent, idx, nb_periods, i); 
     464                            } 
     465                        } 
    425466                    default: 
    426467                        break; 
    427468                } 
    428469            } 
    429         } 
    430          
     470            for (i=0; i < nb_out_channels; i++) { 
     471                if (ffado_streaming_get_playback_stream_type(dev,i) == ffado_stream_type_midi) { 
     472                    uint32_t *midievent = (uint32_t *)audiobuffers_out[i]; 
     473                    *midievent = 0x010000FF; 
     474                    break; 
     475                } 
     476            } 
     477 
     478        } 
     479 
    431480        ffado_streaming_transfer_playback_buffers(dev); 
    432          
     481 
    433482        nb_periods++; 
    434483        frame_counter += arguments.period; 
  • trunk/libffado/tests/test-ieee1394service.cpp

    r789 r833  
    5656DECLARE_GLOBAL_DEBUG_MODULE; 
    5757 
    58 #define DIFF_CONSIDERED_LARGE 100000 
     58#define DIFF_CONSIDERED_LARGE 3072 
    5959int PORT_TO_USE = 0; 
    6060 
  • trunk/libffado/tests/test-streamdump.cpp

    r742 r833  
    191191 
    192192        if ( pCons->m_iIsoChannel != -1 ) { 
     193            printf( "disconnect\n"); 
    193194            iec61883_cmp_disconnect( pHandle, 
    194195                                     pCons->m_output, 
  • trunk/libffado/tests/test-timestampedbuffer.cpp

    r783 r833  
    282282    t->setVerboseLevel(arguments.verbose); 
    283283 
    284     t->init(); 
    285  
    286284    // Setup the buffer 
    287285    t->setBufferSize(arguments.buffersize);