Changeset 494
- Timestamp:
- 07/24/07 09:49:11 (16 years ago)
- Files:
-
- trunk/libffado/src/debugmodule/debugmodule.cpp (modified) (4 diffs)
- trunk/libffado/src/debugmodule/debugmodule.h (modified) (1 diff)
- trunk/libffado/src/ffado_streaming.cpp (modified) (1 diff)
- trunk/libffado/src/libstreaming/AmdtpSlaveStreamProcessor.cpp (modified) (2 diffs)
- trunk/libffado/src/libstreaming/AmdtpStreamProcessor.cpp (modified) (13 diffs)
- trunk/libffado/src/libstreaming/AmdtpStreamProcessor.h (modified) (1 diff)
- trunk/libffado/src/libstreaming/cycletimer.h (modified) (17 diffs)
- trunk/libffado/src/libstreaming/IsoHandlerManager.cpp (modified) (2 diffs)
- trunk/libffado/src/libstreaming/MotuStreamProcessor.cpp (modified) (1 diff)
- trunk/libffado/src/libstreaming/MotuStreamProcessor.h (modified) (1 diff)
- trunk/libffado/src/libstreaming/StreamProcessor.cpp (modified) (5 diffs)
- trunk/libffado/src/libstreaming/StreamProcessor.h (modified) (4 diffs)
- trunk/libffado/src/libstreaming/StreamProcessorManager.cpp (modified) (3 diffs)
- trunk/libffado/src/libutil/TimestampedBuffer.cpp (modified) (28 diffs)
- trunk/libffado/src/libutil/TimestampedBuffer.h (modified) (7 diffs)
- trunk/libffado/tests/test-timestampedbuffer.cpp (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/libffado/src/debugmodule/debugmodule.cpp
r445 r494 328 328 char msg[MB_BUFFERSIZE]; 329 329 va_list ap; 330 330 unsigned int ntries=5; 331 struct timespec wait = {0,50000}; 332 331 333 /* format the message first, to reduce lock contention */ 332 334 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 } 334 338 va_end(ap); 335 339 … … 341 345 return; 342 346 } 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 */ 349 362 // atomic_add(&mb_overruns, 1); 350 363 // FIXME: atomicity … … 358 371 { 359 372 char msg[MB_BUFFERSIZE]; 373 unsigned int ntries=5; 374 struct timespec wait = {0,50000}; 360 375 361 376 /* 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 364 381 if (!mb_initialized) { 365 382 /* Unable to print message with realtime safety. … … 370 387 } 371 388 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 */ 378 403 // atomic_add(&mb_overruns, 1); 379 404 // FIXME: atomicity trunk/libffado/src/debugmodule/debugmodule.h
r445 r494 35 35 36 36 /* MB_NEXT() relies on the fact that MB_BUFFERS is a power of two */ 37 #define MB_BUFFERS 819237 #define MB_BUFFERS (1<<16) 38 38 #define MB_NEXT(index) ((index+1) & (MB_BUFFERS-1)) 39 39 #define MB_BUFFERSIZE 256 /* message length limit */ trunk/libffado/src/ffado_streaming.cpp
r454 r494 59 59 struct _ffado_device *dev = new struct _ffado_device; 60 60 61 debug Fatal("%s built %s %s\n", ffado_get_version(), __DATE__, __TIME__);61 debugWarning("%s built %s %s\n", ffado_get_version(), __DATE__, __TIME__); 62 62 63 63 if(!dev) { trunk/libffado/src/libstreaming/AmdtpSlaveStreamProcessor.cpp
r445 r494 380 380 // later than expected (the real receive time) 381 381 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()); 383 383 384 384 //=> signal that we're running (if we are) … … 399 399 // SYT_INTERVAL * rate later 400 400 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())); 402 402 403 403 // set the timestamp as if there will be a sample put into trunk/libffado/src/libstreaming/AmdtpStreamProcessor.cpp
r445 r494 34 34 #define TRANSMIT_TRANSFER_DELAY 9000U 35 35 // the number of cycles to send a packet in advance of it's timestamp 36 #define TRANSMIT_ADVANCE_CYCLES 1U36 #define TRANSMIT_ADVANCE_CYCLES 4U 37 37 38 38 namespace Streaming { … … 141 141 } 142 142 143 uint64_t ts_head, fc; 143 uint64_t ts_head; 144 signed int fc; 144 145 if (!m_disabled && m_is_disabled) { // this means that we are trying to enable 145 146 // check if we are on or past the enable point … … 152 153 153 154 // 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 156 159 // the number of cycles the sync source lags (> 0) 157 160 // or leads (< 0) … … 199 202 200 203 // 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; 202 207 203 208 // we send a packet some cycles in advance, to avoid the … … 371 376 // we have to make sure that the buffer HEAD timestamp 372 377 // 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()); 374 379 375 380 m_data_buffer->setTickOffset(offset); … … 446 451 447 452 // 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; 449 455 450 456 // initialize internal buffer … … 457 463 458 464 m_data_buffer->setUpdatePeriod(m_period); 459 m_data_buffer->setNominalRate( m_ticks_per_frame);465 m_data_buffer->setNominalRate(ticks_per_frame); 460 466 461 467 m_data_buffer->setWrapValue(128L*TICKS_PER_SECOND); … … 976 982 // later than expected (the real receive time) 977 983 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()); 979 985 980 986 //=> signal that we're running (if we are) … … 995 1001 // SYT_INTERVAL * rate later 996 1002 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())); 998 1004 999 1005 // set the timestamp as if there will be a sample put into … … 1059 1065 // ISO buffering 1060 1066 int 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())); 1062 1068 } 1063 1069 … … 1131 1137 1132 1138 // 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); 1136 1143 1137 1144 // initialize internal buffer … … 1145 1152 // the buffer is written every syt_interval 1146 1153 m_data_buffer->setUpdatePeriod(m_syt_interval); 1147 m_data_buffer->setNominalRate( m_ticks_per_frame);1154 m_data_buffer->setNominalRate(ticks_per_frame); 1148 1155 1149 1156 m_data_buffer->setWrapValue(128L*TICKS_PER_SECOND); … … 1245 1252 } 1246 1253 1247 bool AmdtpReceiveStreamProcessor::getFrames(unsigned int nbframes ) {1254 bool AmdtpReceiveStreamProcessor::getFrames(unsigned int nbframes, int64_t ts) { 1248 1255 1249 1256 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 1251 1310 // ask the buffer to process nbframes of frames 1252 1311 // using it's registered client's processReadBlock(), trunk/libffado/src/libstreaming/AmdtpStreamProcessor.h
r445 r494 187 187 bool prepareForStart(); 188 188 189 bool getFrames(unsigned int nbframes ); ///< transfer the buffer contents to the client189 bool getFrames(unsigned int nbframes, int64_t ts); ///< transfer the buffer contents to the client 190 190 191 191 // We have 1 period of samples = m_period trunk/libffado/src/libstreaming/cycletimer.h
r445 r494 78 78 * @return wrapped time 79 79 */ 80 static inline uint 32_t wrapAtMaxTicks(uint64_t x) {80 static inline uint64_t wrapAtMaxTicks(uint64_t x) { 81 81 if (x >= TICKS_PER_SECOND * 128L) { 82 82 x -= TICKS_PER_SECOND * 128L; … … 101 101 * @return wrapped time 102 102 */ 103 static inline uint32_t wrapAtMinTicks(int64_t x) {103 static inline int64_t wrapAtMinTicks(int64_t x) { 104 104 if (x < 0) { 105 105 x += TICKS_PER_SECOND * 128L; … … 122 122 #endif 123 123 124 return ( uint32_t)x;124 return (int64_t)x; 125 125 } 126 126 … … 135 135 * @return wrapped value 136 136 */ 137 static inline uint32_t wrapAtMinMaxTicks(int64_t x) {137 static inline int64_t wrapAtMinMaxTicks(int64_t x) { 138 138 139 139 if (x < 0) { … … 170 170 * @return the difference x-y, unwrapped 171 171 */ 172 static inline int 32_t diffTicks(uint32_t x, uint32_t y) {172 static inline int64_t diffTicks(int64_t x, int64_t y) { 173 173 int64_t diff=(int64_t)x - (int64_t)y; 174 174 175 175 // 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; 177 178 178 179 if(diff > max) { … … 181 182 // by adding TICKS_PER_SECOND*128L, meaning that we should substract 182 183 // this value from diff 183 diff -= TICKS_PER_SECOND*128L;184 diff -= wrapvalue; 184 185 } else if (diff < -max) { 185 186 // this means that x has wrapped, but … … 187 188 // by adding TICKS_PER_SECOND*128L, meaning that we should add 188 189 // 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; 193 202 194 203 } … … 204 213 * @return the sum x+y, wrapped 205 214 */ 206 static inline uint 32_t addTicks(uint32_t x, uint32_t y) {215 static inline uint64_t addTicks(uint64_t x, uint64_t y) { 207 216 uint64_t sum=x+y; 208 217 … … 220 229 * @return the difference x-y, wrapped 221 230 */ 222 static inline uint 32_t substractTicks(uint32_t x, uint32_t y) {231 static inline uint64_t substractTicks(uint64_t x, uint64_t y) { 223 232 int64_t subs=x-y; 224 233 … … 235 244 * @return 236 245 */ 237 static inline uint 32_t sytRecvToFullTicks(uint32_t syt_timestamp, unsigned int rcv_cycle, uint32_t ctr_now) {238 uint 32_t timestamp;246 static inline uint64_t sytRecvToFullTicks(uint64_t syt_timestamp, unsigned int rcv_cycle, uint64_t ctr_now) { 247 uint64_t timestamp; 239 248 240 249 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"SYT=%08X CY=%04X CTR=%08X\n", … … 242 251 243 252 // reconstruct the full cycle 244 uint 32_t cc_cycles=CYCLE_TIMER_GET_CYCLES(ctr_now);245 uint 32_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); 246 255 247 256 // the cycletimer has wrapped since this packet was received … … 259 268 260 269 // reconstruct the top part of the timestamp using the current cycle number 261 uint 32_t rcv_cycle_masked=rcv_cycle & 0xF;262 uint 32_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); 263 272 264 273 // if this is true, wraparound has occurred, undo this wraparound … … 267 276 // this is the difference in cycles wrt the cycle the 268 277 // timestamp was received 269 uint 32_t delta_cycles=syt_cycle-rcv_cycle_masked;278 uint64_t delta_cycles=syt_cycle-rcv_cycle_masked; 270 279 271 280 // reconstruct the cycle part of the timestamp 272 uint 32_t new_cycles=rcv_cycle + delta_cycles;281 uint64_t new_cycles=rcv_cycle + delta_cycles; 273 282 274 283 // if the cycles cause a wraparound of the cycle timer, … … 321 330 * @return 322 331 */ 323 static inline uint 32_t sytXmitToFullTicks(uint32_t syt_timestamp, unsigned int xmt_cycle, uint32_t ctr_now) {324 uint 32_t timestamp;332 static inline uint64_t sytXmitToFullTicks(uint64_t syt_timestamp, unsigned int xmt_cycle, uint64_t ctr_now) { 333 uint64_t timestamp; 325 334 326 335 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"SYT=%08X CY=%04X CTR=%08X\n", … … 328 337 329 338 // reconstruct the full cycle 330 uint 32_t cc_cycles=CYCLE_TIMER_GET_CYCLES(ctr_now);331 uint 32_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); 332 341 333 342 // the cycletimer has wrapped since this packet was received … … 345 354 346 355 // reconstruct the top part of the timestamp using the current cycle number 347 uint 32_t xmt_cycle_masked=xmt_cycle & 0xF;348 uint 32_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); 349 358 350 359 // if this is true, wraparound has occurred, undo this wraparound … … 353 362 // this is the difference in cycles wrt the cycle the 354 363 // timestamp was received 355 uint 32_t delta_cycles=syt_cycle-xmt_cycle_masked;364 uint64_t delta_cycles=syt_cycle-xmt_cycle_masked; 356 365 357 366 // reconstruct the cycle part of the timestamp 358 uint 32_t new_cycles=xmt_cycle + delta_cycles;367 uint64_t new_cycles=xmt_cycle + delta_cycles; 359 368 360 369 // if the cycles cause a wraparound of the cycle timer, trunk/libffado/src/libstreaming/IsoHandlerManager.cpp
r445 r494 337 337 // FIXME: test 338 338 irq_interval=1; 339 #warning Using fixed irq_interval 339 340 340 341 unsigned int max_packet_size=getpagesize() / irq_interval; … … 425 426 // FIXME: test 426 427 irq_interval=1; 428 #warning Using fixed irq_interval 427 429 428 430 unsigned int max_packet_size=getpagesize() / irq_interval; trunk/libffado/src/libstreaming/MotuStreamProcessor.cpp
r493 r494 1363 1363 } 1364 1364 1365 bool MotuReceiveStreamProcessor::getFrames(unsigned int nbframes ) {1365 bool MotuReceiveStreamProcessor::getFrames(unsigned int nbframes, int64_t ts) { 1366 1366 1367 1367 m_PeriodStat.mark(m_data_buffer->getBufferFill()); trunk/libffado/src/libstreaming/MotuStreamProcessor.h
r445 r494 126 126 unsigned int cycle, unsigned int dropped); 127 127 128 bool getFrames(unsigned int nbframes ); ///< transfer the buffer contents to the client128 bool getFrames(unsigned int nbframes, int64_t ts); ///< transfer the buffer contents to the client 129 129 130 130 bool init(); trunk/libffado/src/libstreaming/StreamProcessor.cpp
r445 r494 29 29 30 30 #include <assert.h> 31 #include <math.h> 31 32 32 33 namespace Streaming { … … 75 76 debugOutputShort( DEBUG_LEVEL_NORMAL, " enable status : %s\n", m_is_disabled ? "No" : "Yes"); 76 77 78 debugOutputShort( DEBUG_LEVEL_NORMAL, " Nominal framerate : %u\n", m_framerate); 77 79 debugOutputShort( DEBUG_LEVEL_NORMAL, " Device framerate : Sync: %f, Buffer %f\n", 78 80 24576000.0/m_SyncSource->m_data_buffer->getRate(), … … 222 224 m_SyncSource=s; 223 225 return true; 226 } 227 228 float 229 StreamProcessor::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 } 224 243 } 225 244 … … 288 307 289 308 uint64_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); 291 310 292 311 #ifdef DEBUG 293 uint64_t ts,fc; 312 ffado_timestamp_t ts; 313 signed int fc; 314 294 315 m_data_buffer->getBufferTailTimestamp(&ts,&fc); 295 316 296 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> NPD= %11lld, LTS=%11llu, FC=%5u, TPF=%f\n",297 next_period_boundary, ts, fc, m_ticks_per_frame317 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() 298 319 ); 299 320 #endif 300 321 301 return next_period_boundary;322 return (uint64_t)next_period_boundary; 302 323 } 303 324 … … 322 343 323 344 uint64_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); 325 346 326 347 #ifdef DEBUG 327 uint64_t ts,fc; 348 ffado_timestamp_t ts; 349 signed int fc; 328 350 m_data_buffer->getBufferTailTimestamp(&ts,&fc); 329 351 330 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> NPD= %11lld, LTS=%11llu, FC=%5u, TPF=%f\n",331 next_period_boundary, ts, fc, m_ticks_per_frame352 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() 332 354 ); 333 355 #endif 334 356 335 return next_period_boundary;357 return (uint64_t)next_period_boundary; 336 358 } 337 359 trunk/libffado/src/libstreaming/StreamProcessor.h
r445 r494 90 90 91 91 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 client92 virtual bool getFrames(unsigned int nbframes, int64_t ts) = 0; ///< transfer the buffer contents to the client 93 93 94 94 virtual bool reset(); ///< reset the streams & buffers (e.g. after xrun) … … 178 178 * \brief return the time of the next period boundary (in internal units) 179 179 * 180 * The same as getTime UntilNextPeriodSignalUsecs() but in internal units.180 * The same as getTimeAtPeriodUsecs() but in internal units. 181 181 * 182 182 * @return the time in internal units … … 206 206 207 207 bool setSyncSource(StreamProcessor *s); 208 float getTicksPerFrame() {return m_ticks_per_frame;};208 float getTicksPerFrame(); 209 209 210 210 int getLastCycle() {return m_last_cycle;}; … … 275 275 unsigned char channel, unsigned char tag, unsigned char sy, 276 276 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;}; 278 278 279 279 virtual enum raw1394_iso_disposition trunk/libffado/src/libstreaming/StreamProcessorManager.cpp
r493 r494 780 780 781 781 while(time_till_next_period > 0) { 782 debugOutput( DEBUG_LEVEL_VER Y_VERBOSE, "waiting for %d usecs...\n", time_till_next_period);782 debugOutput( DEBUG_LEVEL_VERBOSE, "waiting for %d usecs...\n", time_till_next_period); 783 783 784 784 // wait for the period … … 920 920 // penalty for the virtual functions (to be checked) 921 921 if (t==StreamProcessor::E_Receive) { 922 923 // determine the time at which we want reception to start 924 float rate=m_SyncSource->getTicksPerFrame(); 925 int64_t one_frame_in_ticks=(int64_t)(((float)m_period)*rate); 926 927 int64_t receive_timestamp = substractTicks(m_time_of_transfer,one_frame_in_ticks); 928 929 if(receive_timestamp<0) { 930 debugWarning("receive ts < 0.0 : %lld, m_time_of_transfer= %llu, one_frame_in_ticks=%lld\n", 931 receive_timestamp, m_time_of_transfer, one_frame_in_ticks); 932 } 933 if(receive_timestamp>(128L*TICKS_PER_SECOND)) { 934 debugWarning("receive ts > 128L*TICKS_PER_SECOND : %lld, m_time_of_transfer= %llu, one_frame_in_ticks=%lld\n", 935 receive_timestamp, m_time_of_transfer, one_frame_in_ticks); 936 } 937 922 938 for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 923 939 it != m_ReceiveProcessors.end(); 924 940 ++it ) { 925 941 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", 928 944 m_period, m_time_of_transfer,*it); 929 945 return false; // buffer underrun … … 937 953 938 954 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", 940 956 m_period, m_time_of_transfer, *it); 941 957 return false; // buffer overrun trunk/libffado/src/libutil/TimestampedBuffer.cpp
r493 r494 32 32 #include "TimestampedBuffer.h" 33 33 #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) 34 46 35 47 namespace Util { … … 43 55 m_wrap_at(0xFFFFFFFFFFFFFFFFLLU), 44 56 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), 49 61 m_nominal_rate(0.0), m_update_period(0) 50 62 { … … 94 106 * @return true if successful 95 107 */ 96 bool TimestampedBuffer::setWrapValue( uint64_t w) {108 bool TimestampedBuffer::setWrapValue(ffado_timestamp_t w) { 97 109 m_wrap_at=w; 98 110 return true; 99 111 } 112 #include <math.h> 100 113 101 114 /** … … 107 120 */ 108 121 float 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 109 128 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 } 113 151 } 114 152 … … 164 202 * @return true if successful 165 203 */ 166 bool TimestampedBuffer::setTickOffset( int nticks) {167 debugOutput(DEBUG_LEVEL_VERBOSE,"Setting ticks offset to %d\n",nticks);204 bool TimestampedBuffer::setTickOffset(ffado_timestamp_t nticks) { 205 debugOutput(DEBUG_LEVEL_VERBOSE,"Setting ticks offset to "TIMESTAMP_FORMAT_SPEC"\n",nticks); 168 206 m_tick_offset=nticks; 169 207 return true; … … 219 257 220 258 /** 221 * \brief P erpares the TimestampedBuffer259 * \brief Prepares the TimestampedBuffer 222 260 * 223 261 * Prepare the TimestampedBuffer. This allocates all internal buffers and … … 239 277 m_nominal_rate); 240 278 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); 242 280 243 281 assert(m_buffer_size); … … 264 302 m_dll_e2=m_nominal_rate * (float)m_update_period; 265 303 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 */ 324 bool 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 269 345 return true; 270 346 } … … 281 357 * @return true if successful 282 358 */ 283 bool TimestampedBuffer::writeFrames(unsigned int nframes, char *data, uint64_t ts) {359 bool TimestampedBuffer::writeFrames(unsigned int nframes, char *data, ffado_timestamp_t ts) { 284 360 285 361 unsigned int write_size=nframes*m_event_size*m_events_per_frame; … … 337 413 * @return true if successful 338 414 */ 339 bool TimestampedBuffer::blockProcessWriteFrames(unsigned int nbframes, int64_t ts) {415 bool TimestampedBuffer::blockProcessWriteFrames(unsigned int nbframes, ffado_timestamp_t ts) { 340 416 341 417 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n"); … … 545 621 * @param new_timestamp 546 622 */ 547 void TimestampedBuffer::setBufferTailTimestamp( uint64_t new_timestamp) {623 void TimestampedBuffer::setBufferTailTimestamp(ffado_timestamp_t new_timestamp) { 548 624 549 625 // add the offsets 550 int64_t ts=new_timestamp;626 ffado_timestamp_t ts=new_timestamp; 551 627 ts += m_tick_offset; 552 628 553 if (ts >= (int64_t)m_wrap_at) {629 if (ts >= m_wrap_at) { 554 630 ts -= m_wrap_at; 555 631 } else if (ts < 0) { … … 559 635 #ifdef DEBUG 560 636 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); 565 641 } 566 642 #endif … … 571 647 572 648 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", 578 656 this, new_timestamp, ts, m_buffer_next_tail_timestamp, m_dll_e2, m_nominal_rate); 579 657 … … 592 670 * @param new_timestamp 593 671 */ 594 void TimestampedBuffer::setBufferHeadTimestamp( uint64_t new_timestamp) {672 void TimestampedBuffer::setBufferHeadTimestamp(ffado_timestamp_t new_timestamp) { 595 673 596 674 #ifdef DEBUG 597 675 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); 599 677 } 600 678 #endif 601 679 602 int64_t ts=new_timestamp;680 ffado_timestamp_t ts=new_timestamp; 603 681 604 682 pthread_mutex_lock(&m_framecounter_lock); 605 683 606 684 // 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) { 610 688 ts -= m_wrap_at; 611 689 } else if (ts < 0) { … … 616 694 617 695 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", 623 702 this, new_timestamp, ts, m_buffer_next_tail_timestamp, m_dll_e2, m_nominal_rate); 624 703 … … 635 714 * @param fc address to store the associated framecounter in 636 715 */ 637 void TimestampedBuffer::getBufferHeadTimestamp( uint64_t *ts, uint64_t *fc) {716 void TimestampedBuffer::getBufferHeadTimestamp(ffado_timestamp_t *ts, signed int *fc) { 638 717 // NOTE: this is still ok with threads, because we use *fc to compute 639 718 // the timestamp … … 652 731 * @param fc address to store the associated framecounter in 653 732 */ 654 void TimestampedBuffer::getBufferTailTimestamp( uint64_t *ts, uint64_t *fc) {655 pthread_mutex_lock(&m_framecounter_lock); 656 *fc = (uint64_t)m_framecounter;733 void TimestampedBuffer::getBufferTailTimestamp(ffado_timestamp_t *ts, signed int *fc) { 734 pthread_mutex_lock(&m_framecounter_lock); 735 *fc = m_framecounter; 657 736 *ts = m_buffer_tail_timestamp; 658 737 pthread_mutex_unlock(&m_framecounter_lock); … … 668 747 * @return timestamp value 669 748 */ 670 uint64_t TimestampedBuffer::getTimestampFromTail(int nframes)749 ffado_timestamp_t TimestampedBuffer::getTimestampFromTail(int nframes) 671 750 { 672 751 // ts(x) = m_buffer_tail_timestamp - 673 752 // (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 676 764 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) { 689 770 timestamp -= m_wrap_at; 690 771 } else if(timestamp < 0) { … … 692 773 } 693 774 694 return (uint64_t)timestamp;775 return timestamp; 695 776 } 696 777 … … 704 785 * @return timestamp value 705 786 */ 706 uint64_t TimestampedBuffer::getTimestampFromHead(int nframes)787 ffado_timestamp_t TimestampedBuffer::getTimestampFromHead(int nframes) 707 788 { 708 789 return getTimestampFromTail(m_framecounter-nframes); … … 740 821 * @param new_timestamp the new timestamp 741 822 */ 742 void TimestampedBuffer::incrementFrameCounter(int nbframes, uint64_t new_timestamp) {823 void TimestampedBuffer::incrementFrameCounter(int nbframes, ffado_timestamp_t new_timestamp) { 743 824 744 825 // 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 746 832 if (diff < 0) diff += m_wrap_at; 747 833 … … 750 836 #endif 751 837 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) { 756 842 ts -= m_wrap_at; 757 843 } else if (ts < 0) { … … 759 845 } 760 846 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", 762 849 this, new_timestamp, ts); 763 850 764 851 #ifdef DEBUG 765 852 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); 770 857 } 771 858 #endif 772 859 773 860 // 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); 775 864 776 865 #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", 779 868 this, diff, ts, m_buffer_next_tail_timestamp); 780 869 } … … 785 874 // m_buffer_next_tail_timestamp = m_buffer_tail_timestamp + diff 786 875 787 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p): diff= %lld",876 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p): diff="TIMESTAMP_FORMAT_SPEC" ", 788 877 this, diff); 789 878 790 879 // 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; 792 881 793 882 if(diff > max) { … … 799 888 float err=diff; 800 889 801 debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "diff2= %llderr=%f\n",890 debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "diff2="TIMESTAMP_FORMAT_SPEC" err=%f\n", 802 891 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", 804 893 m_framecounter, m_buffer_tail_timestamp, m_buffer_next_tail_timestamp); 805 894 … … 807 896 m_framecounter += nbframes; 808 897 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 814 903 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", 817 908 m_framecounter, m_buffer_tail_timestamp, m_buffer_next_tail_timestamp); 818 909 819 910 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"", 821 912 m_buffer_next_tail_timestamp); 822 913 823 914 m_buffer_next_tail_timestamp -= m_wrap_at; 824 915 825 debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, " => %011llu\n",916 debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, " => "TIMESTAMP_FORMAT_SPEC"\n", 826 917 m_buffer_next_tail_timestamp); 827 918 828 919 } 829 920 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", 831 922 m_buffer_tail_timestamp, m_buffer_next_tail_timestamp, m_dll_e2, rate); 832 923 … … 834 925 835 926 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", 838 929 ts, m_buffer_tail_timestamp, m_buffer_next_tail_timestamp); 839 930 840 931 } 841 932 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", 844 935 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 845 942 } 846 943 … … 858 955 void TimestampedBuffer::dumpInfo() { 859 956 860 uint64_t ts_head, fc; 957 ffado_timestamp_t ts_head; 958 signed int fc; 861 959 getBufferHeadTimestamp(&ts_head,&fc); 862 960 863 961 #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; 865 963 #endif 866 964 867 965 debugOutputShort( DEBUG_LEVEL_NORMAL, " TimestampedBuffer (%p) info:\n",this); 868 966 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); 872 971 debugOutputShort( DEBUG_LEVEL_NORMAL, " rate : %f (%f)\n",m_dll_e2,m_dll_e2/m_update_period); 873 972 } trunk/libffado/src/libutil/TimestampedBuffer.h
r445 r494 32 32 #include "libutil/ringbuffer.h" 33 33 34 typedef 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 34 39 namespace Util { 40 35 41 36 42 class TimestampedBufferClient; … … 86 92 TimestampedBuffer(TimestampedBufferClient *); 87 93 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); 90 98 bool readFrames(unsigned int nbframes, char *data); 91 99 92 bool blockProcessWriteFrames(unsigned int nbframes, int64_t ts);100 bool blockProcessWriteFrames(unsigned int nbframes, ffado_timestamp_t ts); 93 101 bool blockProcessReadFrames(unsigned int nbframes); 94 102 … … 102 110 unsigned int getBufferSize() {return m_buffer_size;}; 103 111 104 bool setWrapValue(uint64_t w); 112 unsigned int getBytesPerFrame() {return m_bytes_per_frame;}; 113 114 bool setWrapValue(ffado_timestamp_t w); 105 115 106 116 unsigned int getBufferFill(); … … 109 119 int getFrameCounter() {return m_framecounter;}; 110 120 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); 119 129 120 130 // buffer offset stuff 121 131 /// return the tick offset value 122 signed int getTickOffset() {return m_tick_offset;};132 ffado_timestamp_t getTickOffset() {return m_tick_offset;}; 123 133 124 134 bool setFrameOffset(int nframes); 125 bool setTickOffset( int nframes);135 bool setTickOffset(ffado_timestamp_t); 126 136 127 137 // dll stuff … … 137 147 private: 138 148 void decrementFrameCounter(int nbframes); 139 void incrementFrameCounter(int nbframes, uint64_t new_timestamp);149 void incrementFrameCounter(int nbframes, ffado_timestamp_t new_timestamp); 140 150 void resetFrameCounter(); 141 151 … … 151 161 unsigned int m_bytes_per_buffer; 152 162 153 uint64_t m_wrap_at; // value to wrap at163 ffado_timestamp_t m_wrap_at; // value to wrap at 154 164 155 165 TimestampedBufferClient *m_Client; … … 162 172 163 173 // the offset that define the timing of the buffer 164 signed int m_tick_offset;174 ffado_timestamp_t m_tick_offset; 165 175 166 176 // the buffer tail timestamp gives the timestamp of the last frame 167 177 // 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; 170 180 171 181 // this mutex protects the access to the framecounter trunk/libffado/tests/test-timestampedbuffer.cpp
r445 r494 339 339 cycle < arguments.start_at_cycle+arguments.total_cycles; 340 340 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; 342 344 343 345 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; 345 348 346 349 if (timestamp != ts_head) { … … 420 423 421 424 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; 424 428 425 429 // write one packet … … 427 431 428 432 // 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; 431 437 debugOutput(DEBUG_LEVEL_NORMAL, 432 438 " TS after write: HEAD: %011llu, FC=%04u\n", … … 440 446 441 447 // 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; 444 452 debugOutput(DEBUG_LEVEL_NORMAL, 445 453 " TS after write: HEAD: %011llu, FC=%04u\n", … … 520 528 521 529 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; 524 533 525 534 // write one packet … … 527 536 528 537 // 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; 531 542 debugOutput(DEBUG_LEVEL_NORMAL, 532 543 " TS after write: HEAD: %011llu, FC=%04u\n", … … 536 547 ts_tail,fc_tail); 537 548 538 if (fc_head > blocksize) {549 if (fc_head > (signed int)blocksize) { 539 550 debugOutput(DEBUG_LEVEL_NORMAL,"Reading one block (%u frames)\n",blocksize); 540 551 … … 543 554 544 555 // 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; 547 560 debugOutput(DEBUG_LEVEL_NORMAL, 548 561 " TS after read: HEAD: %011llu, FC=%04u\n",