Changeset 1525

Show
Ignore:
Timestamp:
03/28/09 14:24:21 (12 years ago)
Author:
ppalmers
Message:

- Allow to specify the DLL bandwidths for the CycleTimerHelper? and the TimestampedBuffer? in absolute units (Hz). This ensures samplerate-independent operation
- Reduce the default DLL bandwidth for the TimestampedBuffer?'s. This improves timestamp timing with a factor 10x, which should benefit especially the timing sensitive devices (MOTU).
- Allow to specify the DLL bandwith and other transmit settings through the configuration file
- Implement a sanity check for the instantanous samplerate to detect bogus timestamp processing

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/libffado-2.0/config.h.in

    r1496 r1525  
    108108#define IEEE1394SERVICE_USE_CYCLETIMER_DLL                         1 
    109109#define IEEE1394SERVICE_CYCLETIMER_DLL_UPDATE_INTERVAL_USEC   200000 
     110#define IEEE1394SERVICE_CYCLETIMER_DLL_BANDWIDTH_HZ              0.5 
    110111#define IEEE1394SERVICE_MAX_FIREWIRE_PORTS                         4 
    111112#define IEEE1394SERVICE_MIN_SPLIT_TIMEOUT_USECS              1000000 
     
    205206#define STREAMPROCESSORMANAGER_DYNAMIC_SYNC_DELAY           0 
    206207 
    207 // FIXME: note that it will probably be better to use a DLL bandwidth that is  
    208 //        dependant on the sample rate 
    209 #define TIMESTAMPEDBUFFER_DLL_BANDWIDTH                     (0.01) 
     208// the default bandwidth of the stream processor timestamp DLL 
     209#define STREAMPROCESSOR_DLL_BW_HZ                           0.1 
    210210 
    211211// -- AMDTP options -- // 
  • branches/libffado-2.0/src/genericavc/avc_avdevice.cpp

    r1414 r1525  
    529529    } 
    530530 
     531    // get the device specific and/or global SP configuration 
     532    Util::Configuration &config = getDeviceManager().getConfiguration(); 
     533    // base value is the config.h value 
     534    float recv_sp_dll_bw = STREAMPROCESSOR_DLL_BW_HZ; 
     535    float xmit_sp_dll_bw = STREAMPROCESSOR_DLL_BW_HZ; 
     536 
     537    int xmit_max_cycles_early_transmit = AMDTP_MAX_CYCLES_TO_TRANSMIT_EARLY; 
     538    int xmit_transfer_delay = AMDTP_TRANSMIT_TRANSFER_DELAY; 
     539    int xmit_min_cycles_before_presentation = AMDTP_MIN_CYCLES_BEFORE_PRESENTATION; 
     540 
     541    // we can override that globally 
     542    config.getValueForSetting("streaming.common.recv_sp_dll_bw", recv_sp_dll_bw); 
     543    config.getValueForSetting("streaming.common.xmit_sp_dll_bw", xmit_sp_dll_bw); 
     544    config.getValueForSetting("streaming.amdtp.xmit_max_cycles_early_transmit", xmit_max_cycles_early_transmit); 
     545    config.getValueForSetting("streaming.amdtp.xmit_transfer_delay", xmit_transfer_delay); 
     546    config.getValueForSetting("streaming.amdtp.xmit_min_cycles_before_presentation", xmit_min_cycles_before_presentation); 
     547 
     548    // or override in the device section 
     549    uint32_t vendorid = getConfigRom().getNodeVendorId(); 
     550    uint32_t modelid = getConfigRom().getModelId(); 
     551    config.getValueForDeviceSetting(vendorid, modelid, "recv_sp_dll_bw", recv_sp_dll_bw); 
     552    config.getValueForDeviceSetting(vendorid, modelid, "xmit_sp_dll_bw", xmit_sp_dll_bw); 
     553    config.getValueForDeviceSetting(vendorid, modelid, "xmit_max_cycles_early_transmit", xmit_max_cycles_early_transmit); 
     554    config.getValueForDeviceSetting(vendorid, modelid, "xmit_transfer_delay", xmit_transfer_delay); 
     555    config.getValueForDeviceSetting(vendorid, modelid, "xmit_min_cycles_before_presentation", xmit_min_cycles_before_presentation); 
     556 
     557    // initialize the SP's 
    531558    debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing receive processor...\n"); 
    532559    // create & add streamprocessors 
     
    549576        Streaming::Port::E_Capture)) { 
    550577        debugFatal("Could not add plug to processor!\n"); 
     578        delete p; 
     579        return false; 
     580    } 
     581 
     582    if(!p->setDllBandwidth(recv_sp_dll_bw)) { 
     583        debugFatal("Could not set DLL bandwidth\n"); 
    551584        delete p; 
    552585        return false; 
     
    568601        #if AMDTP_ALLOW_PAYLOAD_IN_NODATA_XMIT 
    569602            // FIXME: it seems that some BeBoB devices can't handle NO-DATA without payload 
     603            // FIXME: make this a config value too 
    570604            t->sendPayloadForNoDataPackets(true); 
    571605        #endif 
     606 
     607        // transmit control parameters 
     608        t->setMaxCyclesToTransmitEarly(xmit_max_cycles_early_transmit); 
     609        t->setTransferDelay(xmit_transfer_delay); 
     610        t->setMinCyclesBeforePresentation(xmit_min_cycles_before_presentation); 
     611 
    572612        p=t; 
    573613    } 
     
    586626            return false; 
    587627        } 
     628        if(!p->setDllBandwidth(recv_sp_dll_bw)) { 
     629            debugFatal("Could not set DLL bandwidth\n"); 
     630            delete p; 
     631            return false; 
     632        } 
    588633    } else { 
    589634        if (!addPlugToProcessor(*inputPlug, p, 
    590635            Streaming::Port::E_Playback)) { 
    591636            debugFatal("Could not add plug to processor!\n"); 
     637            return false; 
     638        } 
     639        if(!p->setDllBandwidth(xmit_sp_dll_bw)) { 
     640            debugFatal("Could not set DLL bandwidth\n"); 
     641            delete p; 
    592642            return false; 
    593643        } 
  • branches/libffado-2.0/src/libieee1394/CycleTimerHelper.cpp

    r1524 r1525  
    3232 
    3333#define DLL_PI        (3.141592653589793238) 
     34#define DLL_2PI       (2 * DLL_PI) 
    3435#define DLL_SQRT2     (1.414213562373095049) 
    35  
    36 // the high-bandwidth coefficients are used 
    37 // to speed up inital tracking 
    38 #define DLL_BANDWIDTH_HIGH (0.1) 
    39 #define DLL_OMEGA_HIGH     (2.0*DLL_PI*DLL_BANDWIDTH_HIGH) 
    40 #define DLL_COEFF_B_HIGH   (DLL_SQRT2 * DLL_OMEGA_HIGH) 
    41 #define DLL_COEFF_C_HIGH   (DLL_OMEGA_HIGH * DLL_OMEGA_HIGH) 
    42  
    43 // the low-bandwidth coefficients are used once we have a 
    44 // good estimate of the internal parameters 
    45 #define DLL_BANDWIDTH (0.1) 
    46 #define DLL_OMEGA     (2.0*DLL_PI*DLL_BANDWIDTH) 
    47 #define DLL_COEFF_B   (DLL_SQRT2 * DLL_OMEGA) 
    48 #define DLL_COEFF_C   (DLL_OMEGA * DLL_OMEGA) 
    49  
    50 // is 1 sec 
    51 #define UPDATES_WITH_HIGH_BANDWIDTH \ 
    52          (1000000 / IEEE1394SERVICE_CYCLETIMER_DLL_UPDATE_INTERVAL_USEC) 
    5336 
    5437IMPL_DEBUG_MODULE( CycleTimerHelper, CycleTimerHelper, DEBUG_LEVEL_NORMAL ); 
     
    6851    , m_cycle_timer_prev ( 0 ) 
    6952    , m_cycle_timer_ticks_prev ( 0 ) 
    70     , m_high_bw_updates ( UPDATES_WITH_HIGH_BANDWIDTH ) 
    7153    , m_current_shadow_idx ( 0 ) 
    7254    , m_Thread ( NULL ) 
     
    7860{ 
    7961    debugOutput( DEBUG_LEVEL_VERBOSE, "Create %p...\n", this); 
     62 
     63    double bw_rel = IEEE1394SERVICE_CYCLETIMER_DLL_BANDWIDTH_HZ*((double)update_period_us)/1e6; 
     64    m_dll_coeff_b = bw_rel * (DLL_SQRT2 * DLL_2PI); 
     65    m_dll_coeff_c = bw_rel * bw_rel * DLL_2PI * DLL_2PI; 
     66 
    8067} 
    8168 
     
    9481    , m_cycle_timer_prev ( 0 ) 
    9582    , m_cycle_timer_ticks_prev ( 0 ) 
    96     , m_high_bw_updates ( UPDATES_WITH_HIGH_BANDWIDTH ) 
    9783    , m_current_shadow_idx ( 0 ) 
    9884    , m_Thread ( NULL ) 
     
    10490{ 
    10591    debugOutput( DEBUG_LEVEL_VERBOSE, "Create %p...\n", this); 
     92 
     93    double bw_rel = IEEE1394SERVICE_CYCLETIMER_DLL_BANDWIDTH_HZ*((double)update_period_us)/1e6; 
     94    m_dll_coeff_b = bw_rel * (DLL_SQRT2 * DLL_2PI); 
     95    m_dll_coeff_c = bw_rel * bw_rel * DLL_2PI * DLL_2PI; 
    10696} 
    10797 
     
    189179    debugOutput( DEBUG_LEVEL_VERBOSE, "requesting DLL re-init...\n" ); 
    190180    Util::SystemTimeSource::SleepUsecRelative(1000); // some time to settle 
    191     m_high_bw_updates = UPDATES_WITH_HIGH_BANDWIDTH; 
    192181    if(!initDLL()) { 
    193182        debugError("(%p) Could not init DLL\n", this); 
     
    283272    uint64_t cycle_timer_ticks; 
    284273 
     274    double bw_rel = m_dll_coeff_b / (DLL_SQRT2 * DLL_2PI); 
     275    double bw_abs = bw_rel / (m_usecs_per_update / 1e6); 
     276    if (bw_rel > 0.5) { 
     277        double bw_max = 0.5 / (m_usecs_per_update / 1e6); 
     278        debugWarning("Specified DLL bandwidth too high (%f > %f), reducing to max." 
     279                     " Increase the DLL update rate to increase the max DLL bandwidth\n", bw_abs, bw_max); 
     280 
     281        bw_rel = 0.49; 
     282        bw_abs = bw_rel / (m_usecs_per_update / 1e6); 
     283        m_dll_coeff_b = bw_rel * (DLL_SQRT2 * DLL_2PI); 
     284        m_dll_coeff_c = bw_rel * bw_rel * DLL_2PI * DLL_2PI; 
     285    } 
     286 
    285287    if(!readCycleTimerWithRetry(&cycle_timer, &local_time, 10)) { 
    286288        debugError("Could not read cycle timer register\n"); 
     
    305307    m_next_time_ticks = addTicks( (uint64_t)m_current_time_ticks, (uint64_t)m_dll_e2); 
    306308    debugOutput(DEBUG_LEVEL_VERBOSE, " (%p) First run\n", this); 
     309    debugOutput(DEBUG_LEVEL_VERBOSE, "  DLL bandwidth: %f Hz (rel: %f)\n",  
     310                bw_abs, bw_rel); 
    307311    debugOutput(DEBUG_LEVEL_VERBOSE, 
    308312                "  usecs/update: %lu, ticks/update: %lu, m_dll_e2: %f\n", 
     
    383387 
    384388        // check for unrealistic CTR reads (NEC controller does that sometimes) 
    385         not_good = (-err_ticks > 1*TICKS_PER_HALFCYCLE || err_ticks > 1*TICKS_PER_HALFCYCLE); 
     389        not_good = (-err_ticks > 1*TICKS_PER_CYCLE || err_ticks > 1*TICKS_PER_CYCLE); 
    386390        if(not_good) { 
    387391            debugOutput(DEBUG_LEVEL_VERBOSE,  
     
    389393                        this, err_ticks, 1*TICKS_PER_CYCLE, ntries, expected_ticks); 
    390394            // sleep half a cycle to make sure the hardware moved on 
    391             Util::SystemTimeSource::SleepUsecRelative(USECS_PER_CYCLE/2); 
     395            Util::SystemTimeSource::SleepUsecRelative(USECS_PER_CYCLE); 
    392396        } 
    393397 
     
    477481 
    478482        // decide what coefficients to use 
    479         double coeff_b, coeff_c; 
    480         if (m_high_bw_updates > 0) { 
    481             coeff_b = DLL_COEFF_B_HIGH; 
    482             coeff_c = DLL_COEFF_C_HIGH; 
    483             m_high_bw_updates--; 
    484             if (m_high_bw_updates == 0) { 
    485                 debugOutput(DEBUG_LEVEL_VERBOSE, 
    486                             "Switching to low-bandwidth coefficients\n"); 
    487             } 
    488         } else { 
    489             coeff_b = DLL_COEFF_B; 
    490             coeff_c = DLL_COEFF_C; 
    491         } 
    492483 
    493484        // it should be ok to not do this in tick space  
     
    500491 
    501492        double diff_ticks_corr_d =  (double)diff_ticks_corr; 
    502         double step_ticks = (coeff_b * diff_ticks_corr_d); 
     493        double step_ticks = (m_dll_coeff_b * diff_ticks_corr_d); 
    503494        debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 
    504495                           "diff_ticks_corr=%f, step_ticks=%f\n", 
     
    528519 
    529520        // update the DLL state 
    530         m_dll_e2 += coeff_c * diff_ticks_corr_d; 
     521        m_dll_e2 += m_dll_coeff_c * diff_ticks_corr_d; 
    531522 
    532523        // update the y-axis values 
  • branches/libffado-2.0/src/libieee1394/CycleTimerHelper.h

    r1341 r1525  
    147147    uint32_t m_cycle_timer_prev; 
    148148    uint64_t m_cycle_timer_ticks_prev; 
    149     int m_high_bw_updates; 
     149 
     150    double m_dll_coeff_b; 
     151    double m_dll_coeff_c; 
    150152 
    151153    // cached vars used for computation 
  • branches/libffado-2.0/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp

    r1524 r1525  
    104104    if(ok) { 
    105105        m_last_timestamp = sytRecvToFullTicks2((uint32_t)CondSwapFromBus16(packet->syt), pkt_ctr); 
     106 
    106107        //#ifdef DEBUG 
    107108        #if 0 
  • branches/libffado-2.0/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp

    r1419 r1525  
    5454        , m_send_nodata_payload ( AMDTP_SEND_PAYLOAD_IN_NODATA_XMIT_BY_DEFAULT ) 
    5555#endif 
     56        , m_max_cycles_to_transmit_early ( AMDTP_MAX_CYCLES_TO_TRANSMIT_EARLY ) 
     57        , m_transmit_transfer_delay ( AMDTP_TRANSMIT_TRANSFER_DELAY ) 
     58        , m_min_cycles_before_presentation ( AMDTP_MIN_CYCLES_BEFORE_PRESENTATION ) 
    5659        , m_nb_audio_ports( 0 ) 
    5760        , m_nb_midi_ports( 0 ) 
     
    103106 
    104107    // now we calculate the time when we have to transmit the sample block 
    105     transmit_at_time = substractTicks( presentation_time, AMDTP_TRANSMIT_TRANSFER_DELAY ); 
     108    transmit_at_time = substractTicks( presentation_time, m_transmit_transfer_delay ); 
    106109 
    107110    // calculate the cycle this block should be presented in 
     
    135138        // we can still postpone the queueing of the packets 
    136139        // if we are far enough ahead of the presentation time 
    137         if ( cycles_until_presentation <= AMDTP_MIN_CYCLES_BEFORE_PRESENTATION
     140        if ( cycles_until_presentation <= m_min_cycles_before_presentation
    138141        { 
    139142            debugOutput( DEBUG_LEVEL_NORMAL, 
     
    206209            // NOTE: dangerous since the device has no way of reporting that it didn't get 
    207210            //       this packet on time. 
    208             if(cycles_until_presentation >= AMDTP_MIN_CYCLES_BEFORE_PRESENTATION
     211            if(cycles_until_presentation >= m_min_cycles_before_presentation
    209212            { 
    210213                // we are not that late and can still try to transmit the packet 
     
    218221            } 
    219222        } 
    220         else if(cycles_until_transmit <= AMDTP_MAX_CYCLES_TO_TRANSMIT_EARLY
     223        else if(cycles_until_transmit <= m_max_cycles_to_transmit_early
    221224        { 
    222225            // it's time send the packet 
     
    242245                               presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time)); 
    243246#ifdef DEBUG 
    244             if ( cycles_until_transmit > AMDTP_MAX_CYCLES_TO_TRANSMIT_EARLY + 1 ) 
     247            if ( cycles_until_transmit > m_max_cycles_to_transmit_early + 1 ) 
    245248            { 
    246249                debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 
     
    429432    m_syt_interval = getSytInterval(); 
    430433    m_fdf = getFDF(); 
     434 
     435    debugOutput ( DEBUG_LEVEL_VERBOSE, " SYT interval / FDF             : %d / %d\n", m_syt_interval, m_fdf ); 
     436#if AMDTP_ALLOW_PAYLOAD_IN_NODATA_XMIT 
     437    debugOutput ( DEBUG_LEVEL_VERBOSE, " Send payload in No-Data packets: %s \n", m_send_nodata_payload?"Yes":"No" ); 
     438#endif 
     439    debugOutput ( DEBUG_LEVEL_VERBOSE, " Max early transmit cycles      : %d\n", m_max_cycles_to_transmit_early ); 
     440    debugOutput ( DEBUG_LEVEL_VERBOSE, " Transfer delay                 : %d\n", m_transmit_transfer_delay ); 
     441    debugOutput ( DEBUG_LEVEL_VERBOSE, " Min cycles before presentation : %d\n", m_min_cycles_before_presentation ); 
    431442 
    432443    iec61883_cip_init ( 
  • branches/libffado-2.0/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h

    r1524 r1525  
    110110    virtual unsigned int getNominalFramesPerPacket() 
    111111                    {return getSytInterval();}; 
     112    // transmit control parameters 
     113    virtual int getMaxCyclesToTransmitEarly() 
     114                    {return m_max_cycles_to_transmit_early;}; 
     115    virtual void setMaxCyclesToTransmitEarly(int x) 
     116                    {m_max_cycles_to_transmit_early = x;}; 
     117    virtual unsigned int getTransferDelay() 
     118                    {return m_transmit_transfer_delay;}; 
     119    virtual void setTransferDelay(unsigned int x) 
     120                    {m_transmit_transfer_delay = x;}; 
     121    virtual int getMinCyclesBeforePresentation() 
     122                    {return m_min_cycles_before_presentation;}; 
     123    virtual void setMinCyclesBeforePresentation(int x) 
     124                    {m_min_cycles_before_presentation = x;}; 
    112125 
    113126protected: 
     
    141154    bool m_send_nodata_payload; 
    142155#endif 
     156    int m_max_cycles_to_transmit_early; 
     157    unsigned int m_transmit_transfer_delay; 
     158    int m_min_cycles_before_presentation; 
    143159 
    144160private: // local port caching for performance 
  • branches/libffado-2.0/src/libstreaming/generic/StreamProcessor.cpp

    r1463 r1525  
    7676    , m_scratch_buffer_size_bytes( 0 ) 
    7777    , m_ticks_per_frame( 0 ) 
     78    , m_dll_bandwidth_hz ( STREAMPROCESSOR_DLL_BW_HZ ) 
    7879    , m_sync_delay( 0 ) 
    7980    , m_in_xrun( false ) 
     
    136137 
    137138int StreamProcessor::getMaxFrameLatency() { 
    138     if (getType() == ePT_Receive) { 
    139         return (int)(m_IsoHandlerManager.getPacketLatencyForStream( this ) * TICKS_PER_CYCLE); 
    140     } else { 
    141         return (int)(m_IsoHandlerManager.getPacketLatencyForStream( this ) * TICKS_PER_CYCLE); 
    142     } 
     139    return (int)(m_IsoHandlerManager.getPacketLatencyForStream( this ) * TICKS_PER_CYCLE); 
    143140} 
    144141 
     
    282279 
    283280bool 
     281StreamProcessor::setDllBandwidth(float bw) 
     282{ 
     283    m_dll_bandwidth_hz = bw; 
     284    return true; 
     285} 
     286 
     287bool 
    284288StreamProcessor::canClientTransferFrames(unsigned int nbframes) 
    285289{ 
     
    397401 
    398402    if (result == eCRV_OK) { 
     403        #ifdef DEBUG 
     404        if (m_last_timestamp > 0 && m_last_timestamp2 > 0) { 
     405            int64_t tsp_diff = diffTicks(m_last_timestamp, m_last_timestamp2); 
     406            debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "TSP diff: %lld\n", tsp_diff); 
     407            double tsp_diff_d = tsp_diff; 
     408            double fs_syt = 1.0/tsp_diff_d; 
     409            fs_syt *= (double)getNominalFramesPerPacket() * (double)TICKS_PER_USEC * 1e6; 
     410            double fs_nom = (double)m_StreamProcessorManager.getNominalRate(); 
     411            double fs_diff = fs_nom - fs_syt; 
     412            double fs_diff_norm = fs_diff/fs_nom; 
     413            debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "Nom fs: %12f, Instantanous fs: %12f, diff: %12f (%12f)\n", 
     414                        fs_nom, fs_syt, fs_diff, fs_diff_norm); 
     415            if (fs_diff_norm > 0.01 || fs_diff_norm < -0.01) { 
     416                debugWarning( "Instantanous samplerate more than 1%% off nominal. [Nom fs: %12f, Instantanous fs: %12f, diff: %12f (%12f)]\n", 
     417                        fs_nom, fs_syt, fs_diff, fs_diff_norm); 
     418            } 
     419        } 
     420        #endif 
     421 
    399422//         #ifdef DEBUG 
    400423        int ticks_per_packet = (int)(getTicksPerFrame() * getNominalFramesPerPacket()); 
     
    702725            } 
    703726            #ifdef DEBUG 
     727            if (m_last_timestamp > 0 && m_last_timestamp2 > 0) { 
     728                int64_t tsp_diff = diffTicks(m_last_timestamp, m_last_timestamp2); 
     729                debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "TSP diff: %lld\n", tsp_diff); 
     730                double tsp_diff_d = tsp_diff; 
     731                double fs_syt = 1.0/tsp_diff_d; 
     732                fs_syt *= (double)getNominalFramesPerPacket() * (double)TICKS_PER_USEC * 1e6; 
     733                double fs_nom = (double)m_StreamProcessorManager.getNominalRate(); 
     734                double fs_diff = fs_nom - fs_syt; 
     735                double fs_diff_norm = fs_diff/fs_nom; 
     736                debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "Nom fs: %12f, Instantanous fs: %12f, diff: %12f (%12f)\n", 
     737                           fs_nom, fs_syt, fs_diff, fs_diff_norm); 
     738                if (fs_diff_norm > 0.01 || fs_diff_norm < -0.01) { 
     739                    debugWarning( "Instantanous samplerate more than 1%% off nominal. [Nom fs: %12f, Instantanous fs: %12f, diff: %12f (%12f)]\n", 
     740                           fs_nom, fs_syt, fs_diff, fs_diff_norm); 
     741                } 
     742            } 
     743 
    704744            int ticks_per_packet = (int)(getTicksPerFrame() * getNominalFramesPerPacket()); 
    705745            int diff = diffTicks(m_last_timestamp, m_last_timestamp2); 
     
    10971137 
    10981138    debugOutput( DEBUG_LEVEL_VERBOSE, "Prepared for:\n"); 
    1099     debugOutput( DEBUG_LEVEL_VERBOSE, " Samplerate: %d\n", 
    1100              m_StreamProcessorManager.getNominalRate()); 
     1139    debugOutput( DEBUG_LEVEL_VERBOSE, " Samplerate: %d  [DLL Bandwidth: %f Hz]\n", 
     1140             m_StreamProcessorManager.getNominalRate(), m_dll_bandwidth_hz); 
    11011141    debugOutput( DEBUG_LEVEL_VERBOSE, " PeriodSize: %d, NbBuffers: %d\n", 
    11021142             m_StreamProcessorManager.getPeriodSize(), m_StreamProcessorManager.getNbBuffers()); 
     
    13581398            m_correct_last_timestamp = false; 
    13591399 
    1360             debugOutput(DEBUG_LEVEL_VERBOSE,"Initializing remote ticks/frame to %f\n", ticks_per_frame); 
     1400            debugOutput(DEBUG_LEVEL_VERBOSE, "Initializing remote ticks/frame to %f\n", ticks_per_frame); 
    13611401 
    13621402            // initialize internal buffer 
     
    13721412            result &= m_data_buffer->setNominalRate(ticks_per_frame); 
    13731413            result &= m_data_buffer->setWrapValue(128L*TICKS_PER_SECOND); 
     1414            result &= m_data_buffer->setBandwidth(m_dll_bandwidth_hz / (double)TICKS_PER_SECOND); 
    13741415            result &= m_data_buffer->prepare(); // FIXME: the name 
     1416 
     1417            debugOutput(DEBUG_LEVEL_VERBOSE, "DLL info: nominal tpf: %f, update period: %d, bandwidth: %e 1/ticks (%e Hz)\n",  
     1418                        m_data_buffer->getNominalRate(), m_data_buffer->getUpdatePeriod(), m_data_buffer->getBandwidth(), m_data_buffer->getBandwidth() * TICKS_PER_SECOND); 
    13751419 
    13761420            break; 
  • branches/libffado-2.0/src/libstreaming/generic/StreamProcessor.h

    r1419 r1525  
    405405        void setTicksPerFrame(float tpf); 
    406406 
     407        bool setDllBandwidth(float bw); 
     408 
    407409        int getBufferFill(); 
    408410 
     
    451453    protected: 
    452454        float m_ticks_per_frame; 
     455        float m_dll_bandwidth_hz; 
    453456        unsigned int m_sync_delay; 
    454457    private: 
  • branches/libffado-2.0/src/libutil/Configuration.cpp

    r1524 r1525  
    270270} 
    271271 
     272bool 
     273Configuration::getValueForSetting(std::string path, float &ref) 
     274{ 
     275    libconfig::Setting *s = getSetting( path ); 
     276    if(s) { 
     277        // FIXME: this can be done using the libconfig methods 
     278        Setting::Type t = s->getType(); 
     279        if(t == Setting::TypeFloat) { 
     280            ref = *s; 
     281            debugOutput(DEBUG_LEVEL_VERBOSE, "path '%s' has value %f\n", path.c_str(), ref); 
     282            return true; 
     283        } else { 
     284            debugOutput(DEBUG_LEVEL_VERBOSE, "path '%s' has wrong type\n", path.c_str()); 
     285            return false; 
     286        } 
     287    } else { 
     288        debugOutput(DEBUG_LEVEL_VERBOSE, "path '%s' not found\n", path.c_str()); 
     289        return false; 
     290    } 
     291} 
     292 
    272293libconfig::Setting * 
    273294Configuration::getSetting( std::string path ) 
     
    308329bool 
    309330Configuration::getValueForDeviceSetting(unsigned int vendor_id, unsigned model_id, std::string setting, int64_t &ref) 
     331{ 
     332    libconfig::Setting *s = getDeviceSetting( vendor_id, model_id ); 
     333    if(s) { 
     334        try { 
     335            return s->lookupValue(setting, ref); 
     336        } catch (...) { 
     337            debugOutput(DEBUG_LEVEL_VERBOSE, "Setting %s not found\n", setting.c_str()); 
     338            return false; 
     339        } 
     340    } else { 
     341        debugOutput(DEBUG_LEVEL_VERBOSE, "device %X/%X not found\n", vendor_id, model_id); 
     342        return false; 
     343    } 
     344} 
     345 
     346bool 
     347Configuration::getValueForDeviceSetting(unsigned int vendor_id, unsigned model_id, std::string setting, float &ref) 
    310348{ 
    311349    libconfig::Setting *s = getDeviceSetting( vendor_id, model_id ); 
  • branches/libffado-2.0/src/libutil/Configuration.h

    r1524 r1525  
    126126    bool getValueForSetting(std::string path, int32_t &ref); 
    127127    bool getValueForSetting(std::string path, int64_t &ref); 
     128    bool getValueForSetting(std::string path, float &ref); 
    128129 
    129130    /** 
     
    141142    bool getValueForDeviceSetting(unsigned int vendor_id, unsigned model_id, std::string setting, int32_t &ref); 
    142143    bool getValueForDeviceSetting(unsigned int vendor_id, unsigned model_id, std::string setting, int64_t &ref); 
     144    bool getValueForDeviceSetting(unsigned int vendor_id, unsigned model_id, std::string setting, float &ref); 
    143145 
    144146    virtual void setVerboseLevel(int l) {setDebugLevel(l);}; 
  • branches/libffado-2.0/src/libutil/TimestampedBuffer.cpp

    r1464 r1525  
    3636#define DLL_PI        (3.141592653589793238) 
    3737#define DLL_SQRT2     (1.414213562373095049) 
    38 #define DLL_OMEGA     (2.0*DLL_PI*TIMESTAMPEDBUFFER_DLL_BANDWIDTH) 
     38#define DLL_2PI       (2.0 * DLL_PI) 
     39 
     40// these are the defaults 
     41#define DLL_OMEGA     (DLL_2PI * 0.01) 
    3942#define DLL_COEFF_B   (DLL_SQRT2 * DLL_OMEGA) 
    4043#define DLL_COEFF_C   (DLL_OMEGA * DLL_OMEGA) 
     
    8487 
    8588/** 
    86  * \brief Set the nominal rate in frames/timeunit 
    87  * 
    88  * Sets the nominal rate in frames per time unit. This rate is used 
     89 * \brief Set the bandwidth of the DLL 
     90 * 
     91 * Sets the bandwith of the DLL in absolute frequency 
     92 * 
     93 * @param bw bandwidth in absolute frequency 
     94 * @return true if successful 
     95 */ 
     96bool TimestampedBuffer::setBandwidth(double bw) { 
     97    double curr_bw = getBandwidth(); 
     98    debugOutput(DEBUG_LEVEL_VERBOSE," bandwidth %e => %e\n", 
     99                                    curr_bw, bw); 
     100    double tupdate = m_nominal_rate * (float)m_update_period; 
     101    double bw_rel = bw * tupdate; 
     102    if(bw_rel >= 0.5) { 
     103        debugError("Requested bandwidth out of range: %f > %f\n", bw, 0.5*tupdate); 
     104        return false; 
     105    } 
     106    m_dll_b = bw_rel * (DLL_SQRT2 * DLL_2PI); 
     107    m_dll_c = bw_rel * bw_rel * DLL_2PI * DLL_2PI; 
     108    return true; 
     109
     110 
     111/** 
     112 * \brief Returns the current bandwidth of the DLL 
     113 * 
     114 * Returns the current bandwith of the DLL in absolute frequency 
     115 * 
     116 * @return bandwidth in absolute frequency 
     117 */ 
     118double TimestampedBuffer::getBandwidth() { 
     119    double tupdate = m_nominal_rate * (float)m_update_period; 
     120    double curr_bw = m_dll_b / (DLL_SQRT2 * DLL_2PI * tupdate); 
     121    return curr_bw; 
     122
     123 
     124 
     125/** 
     126 * \brief Set the nominal rate in timeunits/frame 
     127 * 
     128 * Sets the nominal rate in time units per frame. This rate is used 
    89129 * to initialize the DLL that will extract the effective rate based 
    90130 * upon the timestamps it gets fed. 
     
    94134 */ 
    95135bool TimestampedBuffer::setNominalRate(float r) { 
     136    debugOutput(DEBUG_LEVEL_VERBOSE," nominal rate %e => %e\n", 
     137                                    m_nominal_rate, r); 
    96138    m_nominal_rate=r; 
    97     debugOutput(DEBUG_LEVEL_VERBOSE," nominal rate=%e set to %e\n", 
    98                                     m_nominal_rate, r); 
    99139    return true; 
    100140} 
     
    362402    m_dll_e2=m_nominal_rate * (float)m_update_period; 
    363403 
    364     m_dll_b=((float)(DLL_COEFF_B)); 
    365     m_dll_c=((float)(DLL_COEFF_C)); 
    366      
    367404    // this will init the internal timestamps to a sensible value 
    368405    setBufferTailTimestamp(m_buffer_tail_timestamp); 
     
    958995 
    959996#ifdef DEBUG 
     997 
    960998    // check whether the update is within the allowed bounds 
    961999    ffado_timestamp_t max_abs_diff = 3072/2; // half a cycle is what we consider 'normal' 
  • branches/libffado-2.0/src/libutil/TimestampedBuffer.h

    r1299 r1525  
    136136 
    137137        // dll stuff 
     138        bool setBandwidth(double bw); 
     139        double getBandwidth(); 
    138140        bool setNominalRate ( float r ); 
    139141        float getNominalRate() {return m_nominal_rate;}; 
  • branches/libffado-2.0/src/motu/motu_avdevice.cpp

    r1521 r1525  
    2424 
    2525#include "motu/motu_avdevice.h" 
     26 
     27#include "devicemanager.h" 
    2628 
    2729#include "libieee1394/configrom.h" 
     
    13971399    } 
    13981400 
     1401    // get the device specific and/or global SP configuration 
     1402    Util::Configuration &config = getDeviceManager().getConfiguration(); 
     1403    // base value is the config.h value 
     1404    float recv_sp_dll_bw = STREAMPROCESSOR_DLL_BW_HZ; 
     1405    float xmit_sp_dll_bw = STREAMPROCESSOR_DLL_BW_HZ; 
     1406 
     1407    // we can override that globally 
     1408    config.getValueForSetting("streaming.spm.recv_sp_dll_bw", recv_sp_dll_bw); 
     1409    config.getValueForSetting("streaming.spm.xmit_sp_dll_bw", xmit_sp_dll_bw); 
     1410 
     1411    // or override in the device section 
     1412    config.getValueForDeviceSetting(getConfigRom().getNodeVendorId(), getConfigRom().getModelId(), "recv_sp_dll_bw", recv_sp_dll_bw); 
     1413    config.getValueForDeviceSetting(getConfigRom().getNodeVendorId(), getConfigRom().getModelId(), "xmit_sp_dll_bw", xmit_sp_dll_bw); 
     1414 
    13991415    m_receiveProcessor=new Streaming::MotuReceiveStreamProcessor(*this, event_size_in); 
     1416    m_receiveProcessor->setVerboseLevel(getDebugLevel()); 
    14001417 
    14011418    // The first thing is to initialize the processor.  This creates the 
     
    14051422        return false; 
    14061423    } 
    1407     m_receiveProcessor->setVerboseLevel(getDebugLevel()); 
     1424 
     1425    if(!m_receiveProcessor->setDllBandwidth(recv_sp_dll_bw)) { 
     1426        debugFatal("Could not set DLL bandwidth\n"); 
     1427        delete m_receiveProcessor; 
     1428        m_receiveProcessor = NULL; 
     1429        return false; 
     1430    } 
    14081431 
    14091432    // Now we add ports to the processor 
     
    14671490    } 
    14681491 
     1492    if(!m_transmitProcessor->setDllBandwidth(xmit_sp_dll_bw)) { 
     1493        debugFatal("Could not set DLL bandwidth\n"); 
     1494        delete m_transmitProcessor; 
     1495        m_transmitProcessor = NULL; 
     1496        return false; 
     1497    } 
     1498 
    14691499    // Now we add ports to the processor 
    14701500    debugOutput(DEBUG_LEVEL_VERBOSE,"Adding ports to transmit processor\n");