Changeset 494

Show
Ignore:
Timestamp:
07/24/07 09:49:11 (16 years ago)
Author:
ppalmers
Message:

- switch over to a generic ffado_timestamp_t for the timestamped buffer (currently float)
- implemented some experimental stream phase sync method

- various small things

NOTE: not a very stable commit

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/src/debugmodule/debugmodule.cpp

    r445 r494  
    328328    char msg[MB_BUFFERSIZE]; 
    329329    va_list ap; 
    330  
     330    unsigned int ntries=5; 
     331    struct timespec wait = {0,50000}; 
     332     
    331333    /* format the message first, to reduce lock contention */ 
    332334    va_start(ap, fmt); 
    333     vsnprintf(msg, MB_BUFFERSIZE, fmt, ap); 
     335    if (vsnprintf(msg, MB_BUFFERSIZE, fmt, ap) >= MB_BUFFERSIZE) { 
     336        print("WARNING: message truncated!\n"); 
     337    } 
    334338    va_end(ap); 
    335339 
     
    341345        return; 
    342346    } 
    343     if (pthread_mutex_trylock(&mb_write_lock) == 0) { 
    344         strncpy(mb_buffers[mb_inbuffer], msg, MB_BUFFERSIZE); 
    345         mb_inbuffer = MB_NEXT(mb_inbuffer); 
    346         pthread_cond_signal(&mb_ready_cond); 
    347         pthread_mutex_unlock(&mb_write_lock); 
    348     } else {            /* lock collision */ 
     347     
     348    while (ntries) { // try a few times 
     349        if (pthread_mutex_trylock(&mb_write_lock) == 0) { 
     350            strncpy(mb_buffers[mb_inbuffer], msg, MB_BUFFERSIZE); 
     351            mb_inbuffer = MB_NEXT(mb_inbuffer); 
     352            pthread_cond_signal(&mb_ready_cond); 
     353            pthread_mutex_unlock(&mb_write_lock); 
     354            break; 
     355        } else { 
     356            nanosleep(&wait, NULL); 
     357            ntries--; 
     358        } 
     359    } 
     360     
     361    if (ntries==0) {  /* lock collision */ 
    349362//         atomic_add(&mb_overruns, 1); 
    350363        // FIXME: atomicity 
     
    358371{ 
    359372    char msg[MB_BUFFERSIZE]; 
     373    unsigned int ntries=5; 
     374    struct timespec wait = {0,50000}; 
    360375 
    361376    /* format the message first, to reduce lock contention */ 
    362     vsnprintf(msg, MB_BUFFERSIZE, fmt, ap); 
    363  
     377    if (vsnprintf(msg, MB_BUFFERSIZE, fmt, ap) >= MB_BUFFERSIZE) { 
     378        print("WARNING: message truncated!\n"); 
     379    } 
     380     
    364381    if (!mb_initialized) { 
    365382        /* Unable to print message with realtime safety. 
     
    370387    } 
    371388 
    372     if (pthread_mutex_trylock(&mb_write_lock) == 0) { 
    373         strncpy(mb_buffers[mb_inbuffer], msg, MB_BUFFERSIZE); 
    374         mb_inbuffer = MB_NEXT(mb_inbuffer); 
    375         pthread_cond_signal(&mb_ready_cond); 
    376         pthread_mutex_unlock(&mb_write_lock); 
    377     } else {            /* lock collision */ 
     389    while (ntries) { // try a few times 
     390        if (pthread_mutex_trylock(&mb_write_lock) == 0) { 
     391            strncpy(mb_buffers[mb_inbuffer], msg, MB_BUFFERSIZE); 
     392            mb_inbuffer = MB_NEXT(mb_inbuffer); 
     393            pthread_cond_signal(&mb_ready_cond); 
     394            pthread_mutex_unlock(&mb_write_lock); 
     395            break; 
     396        } else { 
     397            nanosleep(&wait, NULL); 
     398            ntries--; 
     399        } 
     400    } 
     401     
     402    if (ntries==0) {  /* lock collision */ 
    378403//         atomic_add(&mb_overruns, 1); 
    379404        // FIXME: atomicity 
  • trunk/libffado/src/debugmodule/debugmodule.h

    r445 r494  
    3535 
    3636/* MB_NEXT() relies on the fact that MB_BUFFERS is a power of two */ 
    37 #define MB_BUFFERS    8192 
     37#define MB_BUFFERS    (1<<16) 
    3838#define MB_NEXT(index) ((index+1) & (MB_BUFFERS-1)) 
    3939#define MB_BUFFERSIZE    256        /* message length limit */ 
  • trunk/libffado/src/ffado_streaming.cpp

    r454 r494  
    5959    struct _ffado_device *dev = new struct _ffado_device; 
    6060 
    61     debugFatal("%s built %s %s\n", ffado_get_version(), __DATE__, __TIME__); 
     61    debugWarning("%s built %s %s\n", ffado_get_version(), __DATE__, __TIME__); 
    6262 
    6363    if(!dev) { 
  • trunk/libffado/src/libstreaming/AmdtpSlaveStreamProcessor.cpp

    r445 r494  
    380380        // later than expected (the real receive time) 
    381381        debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"STMP: %lluticks | buff=%d, syt_interval=%d, tpf=%f\n", 
    382             m_last_timestamp, m_handler->getWakeupInterval(),m_syt_interval,m_ticks_per_frame); 
     382            m_last_timestamp, m_handler->getWakeupInterval(),m_syt_interval,getTicksPerFrame()); 
    383383 
    384384        //=> signal that we're running (if we are) 
     
    399399            // SYT_INTERVAL * rate later 
    400400            uint64_t ts=addTicks(m_last_timestamp, 
    401                                  (uint64_t)((float)m_syt_interval * m_ticks_per_frame)); 
     401                                 (uint64_t)((float)m_syt_interval * getTicksPerFrame())); 
    402402 
    403403            // set the timestamp as if there will be a sample put into 
  • trunk/libffado/src/libstreaming/AmdtpStreamProcessor.cpp

    r445 r494  
    3434#define TRANSMIT_TRANSFER_DELAY 9000U 
    3535// the number of cycles to send a packet in advance of it's timestamp 
    36 #define TRANSMIT_ADVANCE_CYCLES 1
     36#define TRANSMIT_ADVANCE_CYCLES 4
    3737 
    3838namespace Streaming { 
     
    141141    } 
    142142 
    143     uint64_t ts_head, fc; 
     143    uint64_t ts_head; 
     144    signed int fc; 
    144145    if (!m_disabled && m_is_disabled) { // this means that we are trying to enable 
    145146        // check if we are on or past the enable point 
     
    152153 
    153154            // initialize the buffer head & tail 
    154             m_SyncSource->m_data_buffer->getBufferHeadTimestamp(&ts_head, &fc); // thread safe 
    155  
     155            ffado_timestamp_t ts_head_tmp; 
     156            m_SyncSource->m_data_buffer->getBufferHeadTimestamp(&ts_head_tmp, &fc); // thread safe 
     157            ts_head=(uint64_t)ts_head_tmp; 
     158             
    156159            // the number of cycles the sync source lags (> 0) 
    157160            // or leads (< 0) 
     
    199202 
    200203    // the base timestamp is the one of the next sample in the buffer 
    201     m_data_buffer->getBufferHeadTimestamp(&ts_head, &fc); // thread safe 
     204    ffado_timestamp_t ts_head_tmp; 
     205    m_data_buffer->getBufferHeadTimestamp(&ts_head_tmp, &fc); // thread safe 
     206    ts_head=(uint64_t)ts_head_tmp; 
    202207 
    203208    // we send a packet some cycles in advance, to avoid the 
     
    371376    // we have to make sure that the buffer HEAD timestamp 
    372377    // lies in the future for every possible buffer fill case. 
    373     int offset=(int)(m_ringbuffer_size_frames*m_ticks_per_frame); 
     378    int offset=(int)(m_ringbuffer_size_frames*getTicksPerFrame()); 
    374379 
    375380    m_data_buffer->setTickOffset(offset); 
     
    446451 
    447452    // prepare the framerate estimate 
    448     m_ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_framerate); 
     453    float ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_framerate); 
     454    m_ticks_per_frame=ticks_per_frame; 
    449455 
    450456    // initialize internal buffer 
     
    457463 
    458464    m_data_buffer->setUpdatePeriod(m_period); 
    459     m_data_buffer->setNominalRate(m_ticks_per_frame); 
     465    m_data_buffer->setNominalRate(ticks_per_frame); 
    460466 
    461467    m_data_buffer->setWrapValue(128L*TICKS_PER_SECOND); 
     
    976982        // later than expected (the real receive time) 
    977983        debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"STMP: %lluticks | buff=%d, syt_interval=%d, tpf=%f\n", 
    978             m_last_timestamp, m_handler->getWakeupInterval(),m_syt_interval,m_ticks_per_frame); 
     984            m_last_timestamp, m_handler->getWakeupInterval(),m_syt_interval,getTicksPerFrame()); 
    979985 
    980986        //=> signal that we're running (if we are) 
     
    9951001            // SYT_INTERVAL * rate later 
    9961002            uint64_t ts=addTicks(m_last_timestamp, 
    997                                  (uint64_t)((float)m_syt_interval * m_ticks_per_frame)); 
     1003                                 (uint64_t)((float)m_syt_interval * getTicksPerFrame())); 
    9981004 
    9991005            // set the timestamp as if there will be a sample put into 
     
    10591065// ISO buffering 
    10601066int AmdtpReceiveStreamProcessor::getMinimalSyncDelay() { 
    1061     return ((int)(m_handler->getWakeupInterval() * m_syt_interval * m_ticks_per_frame)); 
     1067    return ((int)(m_handler->getWakeupInterval() * m_syt_interval * getTicksPerFrame())); 
    10621068} 
    10631069 
     
    11311137 
    11321138    // prepare the framerate estimate 
    1133     m_ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_framerate); 
    1134  
    1135     debugOutput(DEBUG_LEVEL_VERBOSE,"Initializing remote ticks/frame to %f\n",m_ticks_per_frame); 
     1139    float ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_framerate); 
     1140    m_ticks_per_frame=ticks_per_frame; 
     1141 
     1142    debugOutput(DEBUG_LEVEL_VERBOSE,"Initializing remote ticks/frame to %f\n",ticks_per_frame); 
    11361143 
    11371144    // initialize internal buffer 
     
    11451152    // the buffer is written every syt_interval 
    11461153    m_data_buffer->setUpdatePeriod(m_syt_interval); 
    1147     m_data_buffer->setNominalRate(m_ticks_per_frame); 
     1154    m_data_buffer->setNominalRate(ticks_per_frame); 
    11481155 
    11491156    m_data_buffer->setWrapValue(128L*TICKS_PER_SECOND); 
     
    12451252} 
    12461253 
    1247 bool AmdtpReceiveStreamProcessor::getFrames(unsigned int nbframes) { 
     1254bool AmdtpReceiveStreamProcessor::getFrames(unsigned int nbframes, int64_t ts) { 
    12481255 
    12491256    m_PeriodStat.mark(m_data_buffer->getBufferFill()); 
    1250  
     1257    uint64_t ts_head; 
     1258    signed int fc; 
     1259    int32_t lag_ticks; 
     1260    float lag_frames; 
     1261 
     1262    // in order to sync up multiple received streams, we should  
     1263    // use the ts parameter. It specifies the time of the block's  
     1264    // first sample. 
     1265     
     1266    ffado_timestamp_t ts_head_tmp; 
     1267    m_data_buffer->getBufferHeadTimestamp(&ts_head_tmp, &fc); 
     1268    ts_head=(uint64_t)ts_head_tmp; 
     1269    lag_ticks=diffTicks(ts, ts_head); 
     1270    float rate=m_data_buffer->getRate(); 
     1271     
     1272    assert(rate!=0.0); 
     1273     
     1274    lag_frames=(((float)lag_ticks)/rate); 
     1275     
     1276    if (lag_frames>=1.0) { 
     1277        // the stream leads 
     1278        debugOutput( DEBUG_LEVEL_VERBOSE, "stream (%p): lags  with %6d ticks = %10.5f frames (rate=%10.5f)\n",this,lag_ticks,lag_frames,rate); 
     1279         
     1280        if (lag_frames>=10.0) { 
     1281            debugOutput( DEBUG_LEVEL_VERBOSE, "  %lld, %llu, %d\n", ts, ts_head, fc); 
     1282        } 
     1283         
     1284        // ditch the excess frames 
     1285        char dummy[m_data_buffer->getBytesPerFrame()]; // one frame of garbage 
     1286        int frames_to_ditch=(int)(lag_frames); 
     1287        debugOutput( DEBUG_LEVEL_VERBOSE, "stream (%p): ditching %d frames (@ ts=%lld)\n",this,frames_to_ditch,ts); 
     1288         
     1289        while (frames_to_ditch--) { 
     1290//             m_data_buffer->readFrames(1, dummy); 
     1291        } 
     1292         
     1293    } else if (lag_frames<=-1.0) { 
     1294        // the stream leads 
     1295        debugOutput( DEBUG_LEVEL_VERBOSE, "stream (%p): leads with %6d ticks = %10.5f frames (rate=%10.5f)\n",this,lag_ticks,lag_frames,rate); 
     1296         
     1297        if (lag_frames<=-10.0) { 
     1298            debugOutput( DEBUG_LEVEL_VERBOSE, "  %lld, %llu, %d\n", ts, ts_head, fc); 
     1299        } 
     1300         
     1301        // add some padding frames 
     1302        int frames_to_add=(int)lag_frames; 
     1303        debugOutput( DEBUG_LEVEL_VERBOSE, "stream (%p): adding %d frames (@ ts=%lld)\n",this,-frames_to_add,ts); 
     1304         
     1305        while (frames_to_add++) { 
     1306//             m_data_buffer->writeDummyFrame(); 
     1307        } 
     1308    } 
     1309     
    12511310    // ask the buffer to process nbframes of frames 
    12521311    // using it's registered client's processReadBlock(), 
  • trunk/libffado/src/libstreaming/AmdtpStreamProcessor.h

    r445 r494  
    187187    bool prepareForStart(); 
    188188 
    189     bool getFrames(unsigned int nbframes); ///< transfer the buffer contents to the client 
     189    bool getFrames(unsigned int nbframes, int64_t ts); ///< transfer the buffer contents to the client 
    190190 
    191191    // We have 1 period of samples = m_period 
  • trunk/libffado/src/libstreaming/cycletimer.h

    r445 r494  
    7878 * @return wrapped time 
    7979 */ 
    80 static inline uint32_t wrapAtMaxTicks(uint64_t x) { 
     80static inline uint64_t wrapAtMaxTicks(uint64_t x) { 
    8181    if (x >= TICKS_PER_SECOND * 128L) { 
    8282        x -= TICKS_PER_SECOND * 128L; 
     
    101101 * @return wrapped time 
    102102 */ 
    103 static inline uint32_t wrapAtMinTicks(int64_t x) { 
     103static inline int64_t wrapAtMinTicks(int64_t x) { 
    104104    if (x < 0) { 
    105105        x += TICKS_PER_SECOND * 128L; 
     
    122122#endif 
    123123 
    124     return (uint32_t)x; 
     124    return (int64_t)x; 
    125125} 
    126126 
     
    135135 * @return wrapped value 
    136136 */ 
    137 static inline uint32_t wrapAtMinMaxTicks(int64_t x) { 
     137static inline int64_t wrapAtMinMaxTicks(int64_t x) { 
    138138 
    139139    if (x < 0) { 
     
    170170 * @return the difference x-y, unwrapped 
    171171 */ 
    172 static inline int32_t diffTicks(uint32_t x, uint32_t y) { 
     172static inline int64_t diffTicks(int64_t x, int64_t y) { 
    173173    int64_t diff=(int64_t)x - (int64_t)y; 
    174174 
    175175    // the maximal difference we allow (64secs) 
    176     const int64_t max=TICKS_PER_SECOND*64L; 
     176    const int64_t wrapvalue=((int64_t)TICKS_PER_SECOND)*128LL; 
     177    const int64_t max=wrapvalue/2LL; 
    177178 
    178179    if(diff > max) { 
     
    181182        // by adding TICKS_PER_SECOND*128L, meaning that we should substract 
    182183        // this value from diff 
    183         diff -= TICKS_PER_SECOND*128L
     184        diff -= wrapvalue
    184185    } else if (diff < -max) { 
    185186        // this means that x has wrapped, but 
     
    187188        // by adding TICKS_PER_SECOND*128L, meaning that we should add 
    188189        // this value to diff 
    189         diff += TICKS_PER_SECOND*128L; 
    190     } 
    191  
    192     return (int32_t)diff; 
     190        diff += wrapvalue; 
     191    } 
     192 
     193#ifdef DEBUG 
     194    if(diff > max || diff < -max) { 
     195        debugWarning("difference does not make any sense\n"); 
     196        debugWarning("diff=%lld max=%ldd\n", diff, max); 
     197         
     198    } 
     199#endif 
     200 
     201    return (int64_t)diff; 
    193202 
    194203} 
     
    204213 * @return the sum x+y, wrapped 
    205214 */ 
    206 static inline uint32_t addTicks(uint32_t x, uint32_t y) { 
     215static inline uint64_t addTicks(uint64_t x, uint64_t y) { 
    207216    uint64_t sum=x+y; 
    208217 
     
    220229 * @return the difference x-y, wrapped 
    221230 */ 
    222 static inline uint32_t substractTicks(uint32_t x, uint32_t y) { 
     231static inline uint64_t substractTicks(uint64_t x, uint64_t y) { 
    223232    int64_t subs=x-y; 
    224233 
     
    235244 * @return 
    236245 */ 
    237 static inline uint32_t sytRecvToFullTicks(uint32_t syt_timestamp, unsigned int rcv_cycle, uint32_t ctr_now) { 
    238     uint32_t timestamp; 
     246static inline uint64_t sytRecvToFullTicks(uint64_t syt_timestamp, unsigned int rcv_cycle, uint64_t ctr_now) { 
     247    uint64_t timestamp; 
    239248 
    240249    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"SYT=%08X CY=%04X CTR=%08X\n", 
     
    242251 
    243252    // reconstruct the full cycle 
    244     uint32_t cc_cycles=CYCLE_TIMER_GET_CYCLES(ctr_now); 
    245     uint32_t cc_seconds=CYCLE_TIMER_GET_SECS(ctr_now); 
     253    uint64_t cc_cycles=CYCLE_TIMER_GET_CYCLES(ctr_now); 
     254    uint64_t cc_seconds=CYCLE_TIMER_GET_SECS(ctr_now); 
    246255 
    247256    // the cycletimer has wrapped since this packet was received 
     
    259268 
    260269    // reconstruct the top part of the timestamp using the current cycle number 
    261     uint32_t rcv_cycle_masked=rcv_cycle & 0xF; 
    262     uint32_t syt_cycle=CYCLE_TIMER_GET_CYCLES(syt_timestamp); 
     270    uint64_t rcv_cycle_masked=rcv_cycle & 0xF; 
     271    uint64_t syt_cycle=CYCLE_TIMER_GET_CYCLES(syt_timestamp); 
    263272 
    264273    // if this is true, wraparound has occurred, undo this wraparound 
     
    267276    // this is the difference in cycles wrt the cycle the 
    268277    // timestamp was received 
    269     uint32_t delta_cycles=syt_cycle-rcv_cycle_masked; 
     278    uint64_t delta_cycles=syt_cycle-rcv_cycle_masked; 
    270279 
    271280    // reconstruct the cycle part of the timestamp 
    272     uint32_t new_cycles=rcv_cycle + delta_cycles; 
     281    uint64_t new_cycles=rcv_cycle + delta_cycles; 
    273282 
    274283    // if the cycles cause a wraparound of the cycle timer, 
     
    321330 * @return 
    322331 */ 
    323 static inline uint32_t sytXmitToFullTicks(uint32_t syt_timestamp, unsigned int xmt_cycle, uint32_t ctr_now) { 
    324     uint32_t timestamp; 
     332static inline uint64_t sytXmitToFullTicks(uint64_t syt_timestamp, unsigned int xmt_cycle, uint64_t ctr_now) { 
     333    uint64_t timestamp; 
    325334 
    326335    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"SYT=%08X CY=%04X CTR=%08X\n", 
     
    328337 
    329338    // reconstruct the full cycle 
    330     uint32_t cc_cycles=CYCLE_TIMER_GET_CYCLES(ctr_now); 
    331     uint32_t cc_seconds=CYCLE_TIMER_GET_SECS(ctr_now); 
     339    uint64_t cc_cycles=CYCLE_TIMER_GET_CYCLES(ctr_now); 
     340    uint64_t cc_seconds=CYCLE_TIMER_GET_SECS(ctr_now); 
    332341 
    333342    // the cycletimer has wrapped since this packet was received 
     
    345354 
    346355    // reconstruct the top part of the timestamp using the current cycle number 
    347     uint32_t xmt_cycle_masked=xmt_cycle & 0xF; 
    348     uint32_t syt_cycle=CYCLE_TIMER_GET_CYCLES(syt_timestamp); 
     356    uint64_t xmt_cycle_masked=xmt_cycle & 0xF; 
     357    uint64_t syt_cycle=CYCLE_TIMER_GET_CYCLES(syt_timestamp); 
    349358 
    350359    // if this is true, wraparound has occurred, undo this wraparound 
     
    353362    // this is the difference in cycles wrt the cycle the 
    354363    // timestamp was received 
    355     uint32_t delta_cycles=syt_cycle-xmt_cycle_masked; 
     364    uint64_t delta_cycles=syt_cycle-xmt_cycle_masked; 
    356365 
    357366    // reconstruct the cycle part of the timestamp 
    358     uint32_t new_cycles=xmt_cycle + delta_cycles; 
     367    uint64_t new_cycles=xmt_cycle + delta_cycles; 
    359368 
    360369    // if the cycles cause a wraparound of the cycle timer, 
  • trunk/libffado/src/libstreaming/IsoHandlerManager.cpp

    r445 r494  
    337337        // FIXME: test 
    338338        irq_interval=1; 
     339#warning Using fixed irq_interval 
    339340 
    340341        unsigned int max_packet_size=getpagesize() / irq_interval; 
     
    425426        // FIXME: test 
    426427        irq_interval=1; 
     428#warning Using fixed irq_interval 
    427429 
    428430        unsigned int max_packet_size=getpagesize() / irq_interval; 
  • trunk/libffado/src/libstreaming/MotuStreamProcessor.cpp

    r493 r494  
    13631363} 
    13641364 
    1365 bool MotuReceiveStreamProcessor::getFrames(unsigned int nbframes) { 
     1365bool MotuReceiveStreamProcessor::getFrames(unsigned int nbframes, int64_t ts) { 
    13661366 
    13671367    m_PeriodStat.mark(m_data_buffer->getBufferFill()); 
  • trunk/libffado/src/libstreaming/MotuStreamProcessor.h

    r445 r494  
    126126                  unsigned int cycle, unsigned int dropped); 
    127127 
    128     bool getFrames(unsigned int nbframes); ///< transfer the buffer contents to the client 
     128    bool getFrames(unsigned int nbframes, int64_t ts); ///< transfer the buffer contents to the client 
    129129 
    130130    bool init(); 
  • trunk/libffado/src/libstreaming/StreamProcessor.cpp

    r445 r494  
    2929 
    3030#include <assert.h> 
     31#include <math.h> 
    3132 
    3233namespace Streaming { 
     
    7576    debugOutputShort( DEBUG_LEVEL_NORMAL, "   enable status        : %s\n", m_is_disabled ? "No" : "Yes"); 
    7677 
     78    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Nominal framerate     : %u\n", m_framerate); 
    7779    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Device framerate      : Sync: %f, Buffer %f\n", 
    7880        24576000.0/m_SyncSource->m_data_buffer->getRate(), 
     
    222224    m_SyncSource=s; 
    223225    return true; 
     226} 
     227 
     228float 
     229StreamProcessor::getTicksPerFrame() { 
     230    if (m_data_buffer) { 
     231        float rate=m_data_buffer->getRate(); 
     232        if (fabsf(m_ticks_per_frame - rate)>(m_ticks_per_frame*0.1)) { 
     233            debugWarning("TimestampedBuffer rate (%10.5f) more that 10%% off nominal (%10.5f)\n",rate,m_ticks_per_frame); 
     234            return m_ticks_per_frame; 
     235        } 
     236//         return m_ticks_per_frame; 
     237        if (rate<0.0) debugError("rate < 0! (%f)\n",rate); 
     238         
     239        return rate; 
     240    } else { 
     241        return 0.0; 
     242    } 
    224243} 
    225244 
     
    288307 
    289308uint64_t ReceiveStreamProcessor::getTimeAtPeriod() { 
    290     uint64_t next_period_boundary=m_data_buffer->getTimestampFromHead(m_period); 
     309    ffado_timestamp_t next_period_boundary=m_data_buffer->getTimestampFromHead(m_period); 
    291310 
    292311    #ifdef DEBUG 
    293     uint64_t ts,fc; 
     312    ffado_timestamp_t ts; 
     313    signed int fc; 
     314     
    294315    m_data_buffer->getBufferTailTimestamp(&ts,&fc); 
    295316 
    296     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> NPD=%11lld, LTS=%11llu, FC=%5u, TPF=%f\n", 
    297         next_period_boundary, ts, fc, m_ticks_per_frame 
     317    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> NPD="TIMESTAMP_FORMAT_SPEC", LTS="TIMESTAMP_FORMAT_SPEC", FC=%5u, TPF=%f\n", 
     318        next_period_boundary, ts, fc, getTicksPerFrame() 
    298319        ); 
    299320    #endif 
    300321 
    301     return next_period_boundary; 
     322    return (uint64_t)next_period_boundary; 
    302323} 
    303324 
     
    322343 
    323344uint64_t TransmitStreamProcessor::getTimeAtPeriod() { 
    324     uint64_t next_period_boundary=m_data_buffer->getTimestampFromTail((m_nb_buffers-1) * m_period); 
     345    ffado_timestamp_t next_period_boundary=m_data_buffer->getTimestampFromTail((m_nb_buffers-1) * m_period); 
    325346 
    326347    #ifdef DEBUG 
    327     uint64_t ts,fc; 
     348    ffado_timestamp_t ts; 
     349    signed int fc; 
    328350    m_data_buffer->getBufferTailTimestamp(&ts,&fc); 
    329351 
    330     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> NPD=%11lld, LTS=%11llu, FC=%5u, TPF=%f\n", 
    331         next_period_boundary, ts, fc, m_ticks_per_frame 
     352    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> NPD="TIMESTAMP_FORMAT_SPEC", LTS="TIMESTAMP_FORMAT_SPEC", FC=%5u, TPF=%f\n", 
     353        next_period_boundary, ts, fc, getTicksPerFrame() 
    332354        ); 
    333355    #endif 
    334356 
    335     return next_period_boundary; 
     357    return (uint64_t)next_period_boundary; 
    336358} 
    337359 
  • trunk/libffado/src/libstreaming/StreamProcessor.h

    r445 r494  
    9090 
    9191    virtual bool putFrames(unsigned int nbframes, int64_t ts) = 0; ///< transfer the buffer contents from client 
    92     virtual bool getFrames(unsigned int nbframes) = 0; ///< transfer the buffer contents to the client 
     92    virtual bool getFrames(unsigned int nbframes, int64_t ts) = 0; ///< transfer the buffer contents to the client 
    9393 
    9494    virtual bool reset(); ///< reset the streams & buffers (e.g. after xrun) 
     
    178178         * \brief return the time of the next period boundary (in internal units) 
    179179         * 
    180          * The same as getTimeUntilNextPeriodSignalUsecs() but in internal units. 
     180         * The same as getTimeAtPeriodUsecs() but in internal units. 
    181181         * 
    182182         * @return the time in internal units 
     
    206206 
    207207        bool setSyncSource(StreamProcessor *s); 
    208         float getTicksPerFrame() {return m_ticks_per_frame;}
     208        float getTicksPerFrame()
    209209 
    210210        int getLastCycle() {return m_last_cycle;}; 
     
    275275                  unsigned char channel, unsigned char tag, unsigned char sy, 
    276276                  unsigned int cycle, unsigned int dropped) {return RAW1394_ISO_STOP;}; 
    277         virtual bool getFrames(unsigned int nbframes) {return false;}; 
     277        virtual bool getFrames(unsigned int nbframes, int64_t ts) {return false;}; 
    278278 
    279279    virtual enum raw1394_iso_disposition 
  • trunk/libffado/src/libstreaming/StreamProcessorManager.cpp

    r493 r494  
    780780 
    781781    while(time_till_next_period > 0) { 
    782         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "waiting for %d usecs...\n", time_till_next_period); 
     782        debugOutput( DEBUG_LEVEL_VERBOSE, "waiting for %d usecs...\n", time_till_next_period); 
    783783 
    784784        // wait for the period 
     
    920920    // penalty for the virtual functions (to be checked) 
    921921    if (t==StreamProcessor::E_Receive) { 
     922         
     923        // determine the time at which we want reception to start 
     924        float rate=m_SyncSource->getTicksPerFrame(); 
     925        int64_t one_frame_in_ticks=(int64_t)(((float)m_period)*rate); 
     926         
     927        int64_t receive_timestamp = substractTicks(m_time_of_transfer,one_frame_in_ticks); 
     928         
     929        if(receive_timestamp<0) { 
     930            debugWarning("receive ts < 0.0 : %lld, m_time_of_transfer= %llu, one_frame_in_ticks=%lld\n", 
     931             receive_timestamp, m_time_of_transfer, one_frame_in_ticks); 
     932        } 
     933        if(receive_timestamp>(128L*TICKS_PER_SECOND)) { 
     934            debugWarning("receive ts > 128L*TICKS_PER_SECOND : %lld, m_time_of_transfer= %llu, one_frame_in_ticks=%lld\n", 
     935             receive_timestamp, m_time_of_transfer, one_frame_in_ticks); 
     936        } 
     937         
    922938        for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    923939                it != m_ReceiveProcessors.end(); 
    924940                ++it ) { 
    925941 
    926             if(!(*it)->getFrames(m_period)) { 
    927                     debugOutput(DEBUG_LEVEL_VERBOSE,"could not getFrames(%u, %11llu) from stream processor (%p)", 
     942            if(!(*it)->getFrames(m_period, receive_timestamp)) { 
     943                    debugOutput(DEBUG_LEVEL_VERBOSE,"could not getFrames(%u, %11llu) from stream processor (%p)\n", 
    928944                            m_period, m_time_of_transfer,*it); 
    929945                    return false; // buffer underrun 
     
    937953 
    938954            if(!(*it)->putFrames(m_period, (int64_t)m_time_of_transfer)) { 
    939                 debugOutput(DEBUG_LEVEL_VERBOSE, "could not putFrames(%u,%llu) to stream processor (%p)", 
     955                debugOutput(DEBUG_LEVEL_VERBOSE, "could not putFrames(%u,%llu) to stream processor (%p)\n", 
    940956                        m_period, m_time_of_transfer, *it); 
    941957                return false; // buffer overrun 
  • trunk/libffado/src/libutil/TimestampedBuffer.cpp

    r493 r494  
    3232#include "TimestampedBuffer.h" 
    3333#include "assert.h" 
     34 
     35// FIXME: note that it will probably be better to use a DLL bandwidth that is  
     36//        dependant on the sample rate 
     37 
     38 
     39// #define DLL_BANDWIDTH (4800/48000.0) 
     40#define DLL_BANDWIDTH (0.01) 
     41#define DLL_PI        (3.141592653589793238) 
     42#define DLL_SQRT2     (1.414213562373095049) 
     43#define DLL_OMEGA     (2.0*DLL_PI*DLL_BANDWIDTH) 
     44#define DLL_COEFF_B   (DLL_SQRT2 * DLL_OMEGA) 
     45#define DLL_COEFF_C   (DLL_OMEGA * DLL_OMEGA) 
    3446 
    3547namespace Util { 
     
    4355      m_wrap_at(0xFFFFFFFFFFFFFFFFLLU), 
    4456      m_Client(c), m_framecounter(0), 
    45       m_tick_offset(0), 
    46       m_buffer_tail_timestamp(0), 
    47       m_buffer_next_tail_timestamp(0), 
    48       m_dll_e2(0.0), m_dll_b(0.877), m_dll_c(0.384), 
     57      m_tick_offset(0.0), 
     58      m_buffer_tail_timestamp(0.0), 
     59      m_buffer_next_tail_timestamp(0.0), 
     60      m_dll_e2(0.0), m_dll_b(DLL_COEFF_B), m_dll_c(DLL_COEFF_C), 
    4961      m_nominal_rate(0.0), m_update_period(0) 
    5062{ 
     
    94106 * @return true if successful 
    95107 */ 
    96 bool TimestampedBuffer::setWrapValue(uint64_t w) { 
     108bool TimestampedBuffer::setWrapValue(ffado_timestamp_t w) { 
    97109    m_wrap_at=w; 
    98110    return true; 
    99111} 
     112#include <math.h> 
    100113 
    101114/** 
     
    107120 */ 
    108121float TimestampedBuffer::getRate() { 
     122    ffado_timestamp_t diff; 
     123     
     124    pthread_mutex_lock(&m_framecounter_lock); 
     125    diff=m_buffer_next_tail_timestamp - m_buffer_tail_timestamp; 
     126    pthread_mutex_unlock(&m_framecounter_lock); 
     127     
    109128    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"getRate: %f/%f=%f\n", 
    110         m_dll_e2,(float)m_update_period, m_dll_e2/((float) m_update_period)); 
    111  
    112     return m_dll_e2/((float) m_update_period); 
     129        (float)(diff), 
     130        (float)m_update_period, 
     131        ((float)(diff))/((float) m_update_period)); 
     132     
     133    // the maximal difference we can allow (64secs) 
     134    const ffado_timestamp_t max=m_wrap_at/((ffado_timestamp_t)2); 
     135 
     136    if(diff > max) { 
     137        diff -= m_wrap_at; 
     138    } else if (diff < -max) { 
     139        diff += m_wrap_at; 
     140    } 
     141     
     142    float rate=((float)diff)/((float) m_update_period); 
     143    if (fabsf(m_nominal_rate - rate)>(m_nominal_rate*0.1)) { 
     144        debugWarning("(%p) rate (%10.5f) more that 10%% off nominal (rate=%10.5f, diff="TIMESTAMP_FORMAT_SPEC", update_period=%d)\n", 
     145                     this, rate,m_nominal_rate,diff, m_update_period); 
     146        dumpInfo(); 
     147        return m_nominal_rate; 
     148    } else { 
     149        return rate; 
     150    } 
    113151} 
    114152 
     
    164202 * @return true if successful 
    165203 */ 
    166 bool TimestampedBuffer::setTickOffset(int nticks) { 
    167     debugOutput(DEBUG_LEVEL_VERBOSE,"Setting ticks offset to %d\n",nticks); 
     204bool TimestampedBuffer::setTickOffset(ffado_timestamp_t nticks) { 
     205    debugOutput(DEBUG_LEVEL_VERBOSE,"Setting ticks offset to "TIMESTAMP_FORMAT_SPEC"\n",nticks); 
    168206    m_tick_offset=nticks; 
    169207    return true; 
     
    219257 
    220258/** 
    221  * \brief Perpares the TimestampedBuffer 
     259 * \brief Prepares the TimestampedBuffer 
    222260 * 
    223261 * Prepare the TimestampedBuffer. This allocates all internal buffers and 
     
    239277                                    m_nominal_rate); 
    240278 
    241     debugOutput(DEBUG_LEVEL_VERBOSE," wrapping at %llu\n",m_wrap_at); 
     279    debugOutput(DEBUG_LEVEL_VERBOSE," wrapping at "TIMESTAMP_FORMAT_SPEC"\n",m_wrap_at); 
    242280 
    243281    assert(m_buffer_size); 
     
    264302    m_dll_e2=m_nominal_rate * (float)m_update_period; 
    265303 
    266     m_dll_b=((float)(0.877)); 
    267     m_dll_c=((float)(0.384)); 
    268  
     304    m_dll_b=((float)(DLL_COEFF_B)); 
     305    m_dll_c=((float)(DLL_COEFF_C)); 
     306     
     307    // this will init the internal timestamps to a sensible value 
     308    setBufferTailTimestamp(m_buffer_tail_timestamp); 
     309     
     310    return true; 
     311
     312 
     313/** 
     314 * @brief Insert a dummy frame to the head buffer 
     315 * 
     316 * Writes one frame of dummy data to the head of the buffer. 
     317 * This is to assist the phase sync of several buffers. 
     318 *  
     319 * Note: currently the dummy data is added to the tail of the 
     320 *       buffer, but without updating the timestamp. 
     321 * 
     322 * @return true if successful 
     323 */ 
     324bool TimestampedBuffer::writeDummyFrame() { 
     325 
     326    unsigned int write_size=m_event_size*m_events_per_frame; 
     327     
     328    char dummy[write_size]; // one frame of garbage 
     329    memset(dummy,0,write_size); 
     330 
     331    // add the data payload to the ringbuffer 
     332    if (ffado_ringbuffer_write(m_event_buffer,dummy,write_size) < write_size) 
     333    { 
     334//         debugWarning("writeFrames buffer overrun\n"); 
     335        return false; 
     336    } 
     337 
     338//     incrementFrameCounter(nframes,ts); 
     339     
     340    // increment without updating the DLL 
     341    pthread_mutex_lock(&m_framecounter_lock); 
     342    m_framecounter++; 
     343    pthread_mutex_unlock(&m_framecounter_lock); 
     344     
    269345    return true; 
    270346} 
     
    281357 * @return true if successful 
    282358 */ 
    283 bool TimestampedBuffer::writeFrames(unsigned int nframes, char *data, uint64_t ts) { 
     359bool TimestampedBuffer::writeFrames(unsigned int nframes, char *data, ffado_timestamp_t ts) { 
    284360 
    285361    unsigned int write_size=nframes*m_event_size*m_events_per_frame; 
     
    337413 * @return true if successful 
    338414 */ 
    339 bool TimestampedBuffer::blockProcessWriteFrames(unsigned int nbframes, int64_t ts) { 
     415bool TimestampedBuffer::blockProcessWriteFrames(unsigned int nbframes, ffado_timestamp_t ts) { 
    340416 
    341417    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n"); 
     
    545621 * @param new_timestamp 
    546622 */ 
    547 void TimestampedBuffer::setBufferTailTimestamp(uint64_t new_timestamp) { 
     623void TimestampedBuffer::setBufferTailTimestamp(ffado_timestamp_t new_timestamp) { 
    548624 
    549625    // add the offsets 
    550     int64_t ts=new_timestamp; 
     626    ffado_timestamp_t ts=new_timestamp; 
    551627    ts += m_tick_offset; 
    552628 
    553     if (ts >= (int64_t)m_wrap_at) { 
     629    if (ts >= m_wrap_at) { 
    554630        ts -= m_wrap_at; 
    555631    } else if (ts < 0) { 
     
    559635#ifdef DEBUG 
    560636    if (new_timestamp >= m_wrap_at) { 
    561         debugWarning("timestamp not wrapped: %llu\n",new_timestamp); 
    562     } 
    563     if ((ts >= (int64_t)m_wrap_at) || (ts < 0 )) { 
    564         debugWarning("ts not wrapped correctly: %lld\n",ts); 
     637        debugWarning("timestamp not wrapped: "TIMESTAMP_FORMAT_SPEC"\n",new_timestamp); 
     638    } 
     639    if ((ts >= m_wrap_at) || (ts < 0 )) { 
     640        debugWarning("ts not wrapped correctly: "TIMESTAMP_FORMAT_SPEC"\n",ts); 
    565641    } 
    566642#endif 
     
    571647 
    572648    m_dll_e2=m_update_period * m_nominal_rate; 
    573     m_buffer_next_tail_timestamp = (uint64_t)((float)m_buffer_tail_timestamp + m_dll_e2); 
    574  
    575     pthread_mutex_unlock(&m_framecounter_lock); 
    576  
    577     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Set buffer tail timestamp for (%p) to %11llu => %11lld, NTS=%llu, DLL2=%f, RATE=%f\n", 
     649    m_buffer_next_tail_timestamp = (ffado_timestamp_t)((float)m_buffer_tail_timestamp + m_dll_e2); 
     650 
     651    pthread_mutex_unlock(&m_framecounter_lock); 
     652 
     653    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Set buffer tail timestamp for (%p) to " 
     654                                          TIMESTAMP_FORMAT_SPEC" => "TIMESTAMP_FORMAT_SPEC", NTS=" 
     655                                          TIMESTAMP_FORMAT_SPEC", DLL2=%f, RATE=%f\n", 
    578656                this, new_timestamp, ts, m_buffer_next_tail_timestamp, m_dll_e2, m_nominal_rate); 
    579657 
     
    592670 * @param new_timestamp 
    593671 */ 
    594 void TimestampedBuffer::setBufferHeadTimestamp(uint64_t new_timestamp) { 
     672void TimestampedBuffer::setBufferHeadTimestamp(ffado_timestamp_t new_timestamp) { 
    595673 
    596674#ifdef DEBUG 
    597675    if (new_timestamp >= m_wrap_at) { 
    598         debugWarning("timestamp not wrapped: %llu\n",new_timestamp); 
     676        debugWarning("timestamp not wrapped: "TIMESTAMP_FORMAT_SPEC"\n",new_timestamp); 
    599677    } 
    600678#endif 
    601679 
    602     int64_t ts=new_timestamp; 
     680    ffado_timestamp_t ts=new_timestamp; 
    603681 
    604682    pthread_mutex_lock(&m_framecounter_lock); 
    605683 
    606684    // add the time 
    607     ts += (int64_t)(m_nominal_rate * (float)m_framecounter); 
    608  
    609     if (ts >= (int64_t)m_wrap_at) { 
     685    ts += (ffado_timestamp_t)(m_nominal_rate * (float)m_framecounter); 
     686 
     687    if (ts >= m_wrap_at) { 
    610688        ts -= m_wrap_at; 
    611689    } else if (ts < 0) { 
     
    616694 
    617695    m_dll_e2=m_update_period * m_nominal_rate; 
    618     m_buffer_next_tail_timestamp = (uint64_t)((float)m_buffer_tail_timestamp + m_dll_e2); 
    619  
    620     pthread_mutex_unlock(&m_framecounter_lock); 
    621  
    622     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Set buffer head timestamp for (%p) to %11llu => %11lld, NTS=%llu, DLL2=%f, RATE=%f\n", 
     696    m_buffer_next_tail_timestamp = (ffado_timestamp_t)((float)m_buffer_tail_timestamp + m_dll_e2); 
     697 
     698    pthread_mutex_unlock(&m_framecounter_lock); 
     699 
     700    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Set buffer head timestamp for (%p) to "TIMESTAMP_FORMAT_SPEC" => " 
     701                                          TIMESTAMP_FORMAT_SPEC", NTS="TIMESTAMP_FORMAT_SPEC", DLL2=%f, RATE=%f\n", 
    623702                this, new_timestamp, ts, m_buffer_next_tail_timestamp, m_dll_e2, m_nominal_rate); 
    624703 
     
    635714 * @param fc address to store the associated framecounter in 
    636715 */ 
    637 void TimestampedBuffer::getBufferHeadTimestamp(uint64_t *ts, uint64_t *fc) { 
     716void TimestampedBuffer::getBufferHeadTimestamp(ffado_timestamp_t *ts, signed int *fc) { 
    638717    // NOTE: this is still ok with threads, because we use *fc to compute 
    639718    //       the timestamp 
     
    652731 * @param fc address to store the associated framecounter in 
    653732 */ 
    654 void TimestampedBuffer::getBufferTailTimestamp(uint64_t *ts, uint64_t *fc) { 
    655     pthread_mutex_lock(&m_framecounter_lock); 
    656     *fc = (uint64_t)m_framecounter; 
     733void TimestampedBuffer::getBufferTailTimestamp(ffado_timestamp_t *ts, signed int *fc) { 
     734    pthread_mutex_lock(&m_framecounter_lock); 
     735    *fc = m_framecounter; 
    657736    *ts = m_buffer_tail_timestamp; 
    658737    pthread_mutex_unlock(&m_framecounter_lock); 
     
    668747 * @return timestamp value 
    669748 */ 
    670 uint64_t TimestampedBuffer::getTimestampFromTail(int nframes) 
     749ffado_timestamp_t TimestampedBuffer::getTimestampFromTail(int nframes) 
    671750{ 
    672751    // ts(x) = m_buffer_tail_timestamp - 
    673752    //         (m_buffer_next_tail_timestamp - m_buffer_tail_timestamp)/(samples_between_updates)*(x) 
    674  
    675     int64_t diff=m_buffer_next_tail_timestamp - m_buffer_tail_timestamp; 
     753    ffado_timestamp_t diff; 
     754    float rate; 
     755    ffado_timestamp_t timestamp; 
     756     
     757    pthread_mutex_lock(&m_framecounter_lock); 
     758     
     759    diff=m_buffer_next_tail_timestamp - m_buffer_tail_timestamp; 
     760    timestamp=m_buffer_tail_timestamp; 
     761     
     762    pthread_mutex_unlock(&m_framecounter_lock); 
     763     
    676764    if (diff < 0) diff += m_wrap_at; 
    677  
    678     float rate=(float)diff / (float)m_update_period; 
    679  
    680     int64_t timestamp; 
    681  
    682     pthread_mutex_lock(&m_framecounter_lock); 
    683  
    684     timestamp=(int64_t)m_buffer_tail_timestamp - (int64_t)((nframes) * rate); 
    685  
    686     pthread_mutex_unlock(&m_framecounter_lock); 
    687  
    688     if(timestamp >= (int64_t)m_wrap_at) { 
     765    rate=(float)diff / (float)m_update_period; 
     766 
     767    timestamp-=(ffado_timestamp_t)((nframes) * rate); 
     768 
     769    if(timestamp >= m_wrap_at) { 
    689770        timestamp -= m_wrap_at; 
    690771    } else if(timestamp < 0) { 
     
    692773    } 
    693774 
    694     return (uint64_t)timestamp; 
     775    return timestamp; 
    695776} 
    696777 
     
    704785 * @return timestamp value 
    705786 */ 
    706 uint64_t TimestampedBuffer::getTimestampFromHead(int nframes) 
     787ffado_timestamp_t TimestampedBuffer::getTimestampFromHead(int nframes) 
    707788{ 
    708789    return getTimestampFromTail(m_framecounter-nframes); 
     
    740821 * @param new_timestamp the new timestamp 
    741822 */ 
    742 void TimestampedBuffer::incrementFrameCounter(int nbframes, uint64_t new_timestamp) { 
     823void TimestampedBuffer::incrementFrameCounter(int nbframes, ffado_timestamp_t new_timestamp) { 
    743824 
    744825    // add the offsets 
    745     int64_t diff=m_buffer_next_tail_timestamp - m_buffer_tail_timestamp; 
     826    ffado_timestamp_t diff; 
     827     
     828    pthread_mutex_lock(&m_framecounter_lock); 
     829    diff=m_buffer_next_tail_timestamp - m_buffer_tail_timestamp; 
     830    pthread_mutex_unlock(&m_framecounter_lock); 
     831 
    746832    if (diff < 0) diff += m_wrap_at; 
    747833 
     
    750836#endif 
    751837 
    752     int64_t ts=new_timestamp; 
    753     ts += (int64_t)m_tick_offset; 
    754  
    755     if (ts >= (int64_t)m_wrap_at) { 
     838    ffado_timestamp_t ts=new_timestamp; 
     839    ts += m_tick_offset; 
     840 
     841    if (ts >= m_wrap_at) { 
    756842        ts -= m_wrap_at; 
    757843    } else if (ts < 0) { 
     
    759845    } 
    760846 
    761     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Setting buffer tail timestamp for (%p) to %11llu => %11lld\n", 
     847    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Setting buffer tail timestamp for (%p) to " 
     848                                          TIMESTAMP_FORMAT_SPEC" => "TIMESTAMP_FORMAT_SPEC"\n", 
    762849                this, new_timestamp, ts); 
    763850 
    764851#ifdef DEBUG 
    765852    if (new_timestamp >= m_wrap_at) { 
    766         debugWarning("timestamp not wrapped: %llu\n",new_timestamp); 
    767     } 
    768     if ((ts >= (int64_t)m_wrap_at) || (ts < 0 )) { 
    769         debugWarning("ts not wrapped correctly: %lld\n",ts); 
     853        debugWarning("timestamp not wrapped: "TIMESTAMP_FORMAT_SPEC"\n",new_timestamp); 
     854    } 
     855    if ((ts >= m_wrap_at) || (ts < 0 )) { 
     856        debugWarning("ts not wrapped correctly: "TIMESTAMP_FORMAT_SPEC"\n",ts); 
    770857    } 
    771858#endif 
    772  
     859     
    773860    // update the DLL 
    774     diff = ts-(int64_t)m_buffer_next_tail_timestamp; 
     861    pthread_mutex_lock(&m_framecounter_lock); 
     862    diff = ts-m_buffer_next_tail_timestamp; 
     863    pthread_mutex_unlock(&m_framecounter_lock); 
    775864 
    776865#ifdef DEBUG 
    777     if ((diff > 1000) || (diff < -1000)) { 
    778         debugWarning("(%p) difference rather large: %lld, %011lld, %011lld\n", 
     866    if ((diff > ((ffado_timestamp_t)1000)) || (diff < ((ffado_timestamp_t)-1000))) { 
     867        debugWarning("(%p) difference rather large: "TIMESTAMP_FORMAT_SPEC", "TIMESTAMP_FORMAT_SPEC", "TIMESTAMP_FORMAT_SPEC"\n", 
    779868            this, diff, ts, m_buffer_next_tail_timestamp); 
    780869    } 
     
    785874    // m_buffer_next_tail_timestamp = m_buffer_tail_timestamp + diff 
    786875 
    787     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p): diff=%lld ", 
     876    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p): diff="TIMESTAMP_FORMAT_SPEC" ", 
    788877                this, diff); 
    789878 
    790879    // the maximal difference we can allow (64secs) 
    791     const int64_t max=m_wrap_at/2; 
     880    const ffado_timestamp_t max=m_wrap_at/2; 
    792881 
    793882    if(diff > max) { 
     
    799888    float err=diff; 
    800889 
    801     debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "diff2=%lld err=%f\n", 
     890    debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "diff2="TIMESTAMP_FORMAT_SPEC" err=%f\n", 
    802891                    diff, err); 
    803     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "B: FC=%10u, TS=%011llu, NTS=%011llu\n", 
     892    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "B: FC=%10u, TS="TIMESTAMP_FORMAT_SPEC", NTS="TIMESTAMP_FORMAT_SPEC"\n", 
    804893                    m_framecounter, m_buffer_tail_timestamp, m_buffer_next_tail_timestamp); 
    805894 
     
    807896    m_framecounter += nbframes; 
    808897 
    809 //    m_buffer_tail_timestamp=m_buffer_next_tail_timestamp; 
    810 //    m_buffer_next_tail_timestamp += (int64_t)(m_dll_b * err + m_dll_e2); 
    811     m_buffer_tail_timestamp=ts; 
    812     m_buffer_next_tail_timestamp += (int64_t)(m_dll_b * err + m_dll_e2); 
    813  
     898    m_buffer_tail_timestamp=m_buffer_next_tail_timestamp; 
     899    m_buffer_next_tail_timestamp += (ffado_timestamp_t)(m_dll_b * err + m_dll_e2); 
     900//     m_buffer_tail_timestamp=ts; 
     901//     m_buffer_next_tail_timestamp += (ffado_timestamp_t)(m_dll_b * err + m_dll_e2); 
     902     
    814903    m_dll_e2 += m_dll_c*err; 
    815  
    816     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "U: FC=%10u, TS=%011llu, NTS=%011llu\n", 
     904     
     905//     debugOutputShort(DEBUG_LEVEL_VERBOSE, "%p %llu %lld %llu %llu %e %e\n", this, new_timestamp, diff, m_buffer_tail_timestamp, m_buffer_next_tail_timestamp, m_dll_e2, 24576000.0/getRate()); 
     906 
     907    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "U: FC=%10u, TS="TIMESTAMP_FORMAT_SPEC", NTS="TIMESTAMP_FORMAT_SPEC"\n", 
    817908                    m_framecounter, m_buffer_tail_timestamp, m_buffer_next_tail_timestamp); 
    818909 
    819910    if (m_buffer_next_tail_timestamp >= m_wrap_at) { 
    820         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Unwrapping next tail timestamp: %011llu", 
     911        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Unwrapping next tail timestamp: "TIMESTAMP_FORMAT_SPEC"", 
    821912                m_buffer_next_tail_timestamp); 
    822913 
    823914        m_buffer_next_tail_timestamp -= m_wrap_at; 
    824915 
    825         debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, " => %011llu\n", 
     916        debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, " => "TIMESTAMP_FORMAT_SPEC"\n", 
    826917                m_buffer_next_tail_timestamp); 
    827918 
    828919    } 
    829920 
    830     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "A: TS=%011llu, NTS=%011llu, DLLe2=%f, RATE=%f\n", 
     921    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "A: TS="TIMESTAMP_FORMAT_SPEC", NTS="TIMESTAMP_FORMAT_SPEC", DLLe2=%f, RATE=%f\n", 
    831922                m_buffer_tail_timestamp, m_buffer_next_tail_timestamp, m_dll_e2, rate); 
    832923 
     
    834925 
    835926    if(m_buffer_tail_timestamp>=m_wrap_at) { 
    836         debugError("Wrapping failed for m_buffer_tail_timestamp! %011llu\n",m_buffer_tail_timestamp); 
    837         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " IN=%011lld, TS=%011llu, NTS=%011llu\n", 
     927        debugError("Wrapping failed for m_buffer_tail_timestamp! "TIMESTAMP_FORMAT_SPEC"\n",m_buffer_tail_timestamp); 
     928        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " IN="TIMESTAMP_FORMAT_SPEC", TS="TIMESTAMP_FORMAT_SPEC", NTS="TIMESTAMP_FORMAT_SPEC"\n", 
    838929                    ts, m_buffer_tail_timestamp, m_buffer_next_tail_timestamp); 
    839930 
    840931    } 
    841932    if(m_buffer_next_tail_timestamp>=m_wrap_at) { 
    842         debugError("Wrapping failed for m_buffer_next_tail_timestamp! %011llu\n",m_buffer_next_tail_timestamp); 
    843         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " IN=%011lld, TS=%011llu, NTS=%011llu\n", 
     933        debugError("Wrapping failed for m_buffer_next_tail_timestamp! "TIMESTAMP_FORMAT_SPEC"\n",m_buffer_next_tail_timestamp); 
     934        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " IN="TIMESTAMP_FORMAT_SPEC", TS="TIMESTAMP_FORMAT_SPEC", NTS="TIMESTAMP_FORMAT_SPEC"\n", 
    844935                    ts, m_buffer_tail_timestamp, m_buffer_next_tail_timestamp); 
     936    } 
     937     
     938    if(m_buffer_tail_timestamp==m_buffer_next_tail_timestamp) { 
     939        debugError("Current and next timestamps are equal: "TIMESTAMP_FORMAT_SPEC" "TIMESTAMP_FORMAT_SPEC"\n", 
     940                   m_buffer_tail_timestamp,m_buffer_next_tail_timestamp); 
     941     
    845942    } 
    846943 
     
    858955void TimestampedBuffer::dumpInfo() { 
    859956 
    860     uint64_t ts_head, fc; 
     957    ffado_timestamp_t ts_head; 
     958    signed int fc; 
    861959    getBufferHeadTimestamp(&ts_head,&fc); 
    862960 
    863961#ifdef DEBUG 
    864     int64_t diff=(int64_t)ts_head - (int64_t)m_buffer_tail_timestamp; 
     962    ffado_timestamp_t diff=(ffado_timestamp_t)ts_head - (ffado_timestamp_t)m_buffer_tail_timestamp; 
    865963#endif 
    866964 
    867965    debugOutputShort( DEBUG_LEVEL_NORMAL, "  TimestampedBuffer (%p) info:\n",this); 
    868966    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Frame counter         : %d\n", m_framecounter); 
    869     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Buffer head timestamp : %011llu\n",ts_head); 
    870     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Buffer tail timestamp : %011llu\n",m_buffer_tail_timestamp); 
    871     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Head - Tail           : %011lld\n",diff); 
     967    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Buffer head timestamp : "TIMESTAMP_FORMAT_SPEC"\n",ts_head); 
     968    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Buffer tail timestamp : "TIMESTAMP_FORMAT_SPEC"\n",m_buffer_tail_timestamp); 
     969    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Next tail timestamp   : "TIMESTAMP_FORMAT_SPEC"\n",m_buffer_next_tail_timestamp); 
     970    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Head - Tail           : "TIMESTAMP_FORMAT_SPEC"\n",diff); 
    872971    debugOutputShort( DEBUG_LEVEL_NORMAL, "  rate                  : %f (%f)\n",m_dll_e2,m_dll_e2/m_update_period); 
    873972} 
  • trunk/libffado/src/libutil/TimestampedBuffer.h

    r445 r494  
    3232#include "libutil/ringbuffer.h" 
    3333 
     34typedef float ffado_timestamp_t; 
     35#define TIMESTAMP_FORMAT_SPEC "%14.3f" 
     36// typedef int64_t ffado_timestamp_t; 
     37// #define TIMESTAMP_FORMAT_SPEC "%012lld" 
     38 
    3439namespace Util { 
     40 
    3541 
    3642class TimestampedBufferClient; 
     
    8692    TimestampedBuffer(TimestampedBufferClient *); 
    8793    virtual ~TimestampedBuffer(); 
    88  
    89     bool writeFrames(unsigned int nbframes, char *data, uint64_t ts); 
     94     
     95    bool writeDummyFrame(); 
     96     
     97    bool writeFrames(unsigned int nbframes, char *data, ffado_timestamp_t ts); 
    9098    bool readFrames(unsigned int nbframes, char *data); 
    9199 
    92     bool blockProcessWriteFrames(unsigned int nbframes, int64_t ts); 
     100    bool blockProcessWriteFrames(unsigned int nbframes, ffado_timestamp_t ts); 
    93101    bool blockProcessReadFrames(unsigned int nbframes); 
    94102 
     
    102110    unsigned int getBufferSize() {return m_buffer_size;}; 
    103111 
    104     bool setWrapValue(uint64_t w); 
     112    unsigned int getBytesPerFrame() {return m_bytes_per_frame;}; 
     113 
     114    bool setWrapValue(ffado_timestamp_t w); 
    105115 
    106116    unsigned int getBufferFill(); 
     
    109119    int getFrameCounter() {return m_framecounter;}; 
    110120 
    111     void getBufferHeadTimestamp(uint64_t *ts, uint64_t *fc); 
    112     void getBufferTailTimestamp(uint64_t *ts, uint64_t *fc); 
    113  
    114     void setBufferTailTimestamp(uint64_t new_timestamp); 
    115     void setBufferHeadTimestamp(uint64_t new_timestamp); 
    116  
    117     uint64_t getTimestampFromTail(int nframes); 
    118     uint64_t getTimestampFromHead(int nframes); 
     121    void getBufferHeadTimestamp(ffado_timestamp_t *ts, signed int *fc); 
     122    void getBufferTailTimestamp(ffado_timestamp_t *ts, signed int *fc); 
     123 
     124    void setBufferTailTimestamp(ffado_timestamp_t new_timestamp); 
     125    void setBufferHeadTimestamp(ffado_timestamp_t new_timestamp); 
     126 
     127    ffado_timestamp_t getTimestampFromTail(int nframes); 
     128    ffado_timestamp_t getTimestampFromHead(int nframes); 
    119129 
    120130    // buffer offset stuff 
    121131    /// return the tick offset value 
    122     signed int getTickOffset() {return m_tick_offset;}; 
     132    ffado_timestamp_t getTickOffset() {return m_tick_offset;}; 
    123133 
    124134    bool setFrameOffset(int nframes); 
    125     bool setTickOffset(int nframes); 
     135    bool setTickOffset(ffado_timestamp_t); 
    126136 
    127137    // dll stuff 
     
    137147private: 
    138148    void decrementFrameCounter(int nbframes); 
    139     void incrementFrameCounter(int nbframes, uint64_t new_timestamp); 
     149    void incrementFrameCounter(int nbframes, ffado_timestamp_t new_timestamp); 
    140150    void resetFrameCounter(); 
    141151 
     
    151161    unsigned int m_bytes_per_buffer; 
    152162 
    153     uint64_t m_wrap_at; // value to wrap at 
     163    ffado_timestamp_t m_wrap_at; // value to wrap at 
    154164 
    155165    TimestampedBufferClient *m_Client; 
     
    162172 
    163173    // the offset that define the timing of the buffer 
    164     signed int m_tick_offset; 
     174    ffado_timestamp_t m_tick_offset; 
    165175 
    166176    // the buffer tail timestamp gives the timestamp of the last frame 
    167177    // that was put into the buffer 
    168     uint64_t   m_buffer_tail_timestamp; 
    169     uint64_t   m_buffer_next_tail_timestamp; 
     178    ffado_timestamp_t   m_buffer_tail_timestamp; 
     179    ffado_timestamp_t   m_buffer_next_tail_timestamp; 
    170180 
    171181    // this mutex protects the access to the framecounter 
  • trunk/libffado/tests/test-timestampedbuffer.cpp

    r445 r494  
    339339            cycle < arguments.start_at_cycle+arguments.total_cycles; 
    340340            cycle++) { 
    341                 uint64_t ts_head, fc_head; 
     341                ffado_timestamp_t ts_head_tmp; 
     342                uint64_t ts_head; 
     343                signed int fc_head; 
    342344 
    343345                t->setBufferHeadTimestamp(timestamp); 
    344                 t->getBufferHeadTimestamp(&ts_head, &fc_head); 
     346                t->getBufferHeadTimestamp(&ts_head_tmp, &fc_head); 
     347                ts_head=(uint64_t)ts_head_tmp; 
    345348 
    346349                if (timestamp != ts_head) { 
     
    420423 
    421424            if(diff>0) { 
    422                 uint64_t ts_head, fc_head; 
    423                 uint64_t ts_tail, fc_tail; 
     425                ffado_timestamp_t ts_head_tmp, ts_tail_tmp; 
     426                uint64_t ts_head, ts_tail; 
     427                signed int fc_head, fc_tail; 
    424428 
    425429                // write one packet 
     
    427431 
    428432                // read the buffer head timestamp 
    429                 t->getBufferHeadTimestamp(&ts_head, &fc_head); 
    430                 t->getBufferTailTimestamp(&ts_tail, &fc_tail); 
     433                t->getBufferHeadTimestamp(&ts_head_tmp, &fc_head); 
     434                t->getBufferTailTimestamp(&ts_tail_tmp, &fc_tail); 
     435                ts_head=(uint64_t)ts_head_tmp; 
     436                ts_tail=(uint64_t)ts_tail_tmp; 
    431437                debugOutput(DEBUG_LEVEL_NORMAL, 
    432438                        " TS after write: HEAD: %011llu, FC=%04u\n", 
     
    440446 
    441447                // read the buffer head timestamp 
    442                 t->getBufferHeadTimestamp(&ts_head, &fc_head); 
    443                 t->getBufferTailTimestamp(&ts_tail, &fc_tail); 
     448                t->getBufferHeadTimestamp(&ts_head_tmp, &fc_head); 
     449                t->getBufferTailTimestamp(&ts_tail_tmp, &fc_tail); 
     450                ts_head=(uint64_t)ts_head_tmp; 
     451                ts_tail=(uint64_t)ts_tail_tmp; 
    444452                debugOutput(DEBUG_LEVEL_NORMAL, 
    445453                        " TS after write: HEAD: %011llu, FC=%04u\n", 
     
    520528 
    521529            if(diff>0) { 
    522                 uint64_t ts_head, fc_head; 
    523                 uint64_t ts_tail, fc_tail; 
     530                ffado_timestamp_t ts_head_tmp, ts_tail_tmp; 
     531                uint64_t ts_head, ts_tail; 
     532                signed int fc_head, fc_tail; 
    524533 
    525534                // write one packet 
     
    527536 
    528537                // read the buffer head timestamp 
    529                 t->getBufferHeadTimestamp(&ts_head, &fc_head); 
    530                 t->getBufferTailTimestamp(&ts_tail, &fc_tail); 
     538                t->getBufferHeadTimestamp(&ts_head_tmp, &fc_head); 
     539                t->getBufferTailTimestamp(&ts_tail_tmp, &fc_tail); 
     540                ts_head=(uint64_t)ts_head_tmp; 
     541                ts_tail=(uint64_t)ts_tail_tmp; 
    531542                debugOutput(DEBUG_LEVEL_NORMAL, 
    532543                        " TS after write: HEAD: %011llu, FC=%04u\n", 
     
    536547                        ts_tail,fc_tail); 
    537548 
    538                 if (fc_head > blocksize) { 
     549                if (fc_head > (signed int)blocksize) { 
    539550                    debugOutput(DEBUG_LEVEL_NORMAL,"Reading one block (%u frames)\n",blocksize); 
    540551 
     
    543554 
    544555                    // read the buffer head timestamp 
    545                     t->getBufferHeadTimestamp(&ts_head, &fc_head); 
    546                     t->getBufferTailTimestamp(&ts_tail, &fc_tail); 
     556                    t->getBufferHeadTimestamp(&ts_head_tmp, &fc_head); 
     557                    t->getBufferTailTimestamp(&ts_tail_tmp, &fc_tail); 
     558                    ts_head=(uint64_t)ts_head_tmp; 
     559                    ts_tail=(uint64_t)ts_tail_tmp; 
    547560                    debugOutput(DEBUG_LEVEL_NORMAL, 
    548561                            " TS after read: HEAD: %011llu, FC=%04u\n",