Changeset 1530
- Timestamp:
- 03/29/09 13:30:46 (14 years ago)
- Files:
-
- branches/libffado-2.0/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp (modified) (1 diff)
- branches/libffado-2.0/src/libstreaming/generic/StreamProcessor.cpp (modified) (5 diffs)
- branches/libffado-2.0/src/libstreaming/generic/StreamProcessor.h (modified) (2 diffs)
- branches/libffado-2.0/src/libstreaming/StreamProcessorManager.cpp (modified) (10 diffs)
- branches/libffado-2.0/src/libutil/TimestampedBuffer.cpp (modified) (13 diffs)
- branches/libffado-2.0/src/libutil/TimestampedBuffer.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/libffado-2.0/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp
r1528 r1530 103 103 if(ok) { 104 104 m_last_timestamp = sytRecvToFullTicks2((uint32_t)CondSwapFromBus16(packet->syt), pkt_ctr); 105 106 105 //#ifdef DEBUG 107 106 #if 0 branches/libffado-2.0/src/libstreaming/generic/StreamProcessor.cpp
r1529 r1530 77 77 , m_ticks_per_frame( 0 ) 78 78 , m_dll_bandwidth_hz ( STREAMPROCESSOR_DLL_BW_HZ ) 79 , m_sync_delay ( 0 )79 , m_sync_delay_frames( 0 ) 80 80 , m_in_xrun( false ) 81 81 { … … 209 209 210 210 void 211 StreamProcessor::setSyncDelay(unsigned int d) { 211 StreamProcessor::setSyncDelay(unsigned int ticks) { 212 213 // round the sync delay to an integer number of packets now we know the frame rate 214 int frames = (int)((float)ticks / getTicksPerFrame()); 215 frames = (frames / getNominalFramesPerPacket()) + 1; 216 frames *= getNominalFramesPerPacket(); 217 212 218 #ifdef DEBUG 213 unsigned int frames = (unsigned int)((float)d / getTicksPerFrame()); 214 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting SP %p SyncDelay to %u ticks, %u frames\n", this, d, frames); 219 float ticks2 = frames * getTicksPerFrame(); 220 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting SP %p SyncDelay to %u ticks => rounded to %u frames, %f ticks\n", 221 this, ticks, frames, ticks2); 215 222 #endif 216 m_sync_delay = d;223 m_sync_delay_frames = frames; 217 224 } 218 225 219 226 unsigned int 220 227 StreamProcessor::getSyncDelayFrames() { 221 unsigned int frames = (unsigned int)((float)m_sync_delay / getTicksPerFrame()); 222 return frames; 228 return m_sync_delay_frames; 229 } 230 231 unsigned int 232 StreamProcessor::getSyncDelay() { 233 return (unsigned int)(m_sync_delay_frames * getTicksPerFrame()); 223 234 } 224 235 … … 414 425 fs_nom, fs_syt, fs_diff, fs_diff_norm); 415 426 } 416 } 417 #endif 418 419 // #ifdef DEBUG 420 int ticks_per_packet = (int)(getTicksPerFrame() * getNominalFramesPerPacket()); 421 int diff = diffTicks(m_last_timestamp, m_last_timestamp2); 422 // display message if the difference between two successive tick 423 // values is more than 50 ticks. 1 sample at 48k is 512 ticks 424 // so 50 ticks = 10%, which is a rather large jitter value. 425 if(diff-ticks_per_packet > 50 || diff-ticks_per_packet < -50) { 426 debugOutput(DEBUG_LEVEL_VERBOSE, 427 "cy %04u rather large TSP difference TS=%011llu => TS=%011llu (%d, nom %d)\n", 428 CYCLE_TIMER_GET_CYCLES(pkt_ctr), m_last_timestamp2, 429 m_last_timestamp, diff, ticks_per_packet); 430 // !!!HACK!!! FIXME: this is the result of a failure in wrapping/unwrapping somewhere 431 // it's definitely a bug. 432 // try to fix up the timestamp 433 int64_t last_timestamp_fixed; 434 // first try to add one second 435 last_timestamp_fixed = addTicks(m_last_timestamp, TICKS_PER_SECOND); 436 diff = diffTicks(last_timestamp_fixed, m_last_timestamp2); 437 if(diff-ticks_per_packet < 50 && diff-ticks_per_packet > -50) { 438 debugWarning("cy %04u rather large TSP difference TS=%011llu => TS=%011llu (%d, nom %d)\n", 439 CYCLE_TIMER_GET_CYCLES(pkt_ctr), m_last_timestamp2, 440 m_last_timestamp, diff, ticks_per_packet); 441 debugWarning("HACK: fixed by adding one second of ticks. This is a bug being run-time fixed.\n"); 442 m_last_timestamp = last_timestamp_fixed; 443 } else { 444 // if that didn't work, try to subtract one second 445 last_timestamp_fixed = substractTicks(m_last_timestamp, TICKS_PER_SECOND); 446 diff = diffTicks(last_timestamp_fixed, m_last_timestamp2); 447 if(diff-ticks_per_packet < 50 && diff-ticks_per_packet > -50) { 448 debugWarning("cy %04u rather large TSP difference TS=%011llu => TS=%011llu (%d, nom %d)\n", 427 428 int ticks_per_packet = (int)(getTicksPerFrame() * getNominalFramesPerPacket()); 429 int diff = diffTicks(m_last_timestamp, m_last_timestamp2); 430 // display message if the difference between two successive tick 431 // values is more than 50 ticks. 1 sample at 48k is 512 ticks 432 // so 50 ticks = 10%, which is a rather large jitter value. 433 if(diff-ticks_per_packet > 50 || diff-ticks_per_packet < -50) { 434 debugOutput(DEBUG_LEVEL_VERBOSE, 435 "cy %04u rather large TSP difference TS=%011llu => TS=%011llu (%d, nom %d)\n", 449 436 CYCLE_TIMER_GET_CYCLES(pkt_ctr), m_last_timestamp2, 450 437 m_last_timestamp, diff, ticks_per_packet); 451 debugWarning("HACK: fixed by subtracing one second of ticks. This is a bug being run-time fixed.\n"); 452 m_last_timestamp = last_timestamp_fixed; 438 // !!!HACK!!! FIXME: this is the result of a failure in wrapping/unwrapping somewhere 439 // it's definitely a bug. 440 // try to fix up the timestamp 441 int64_t last_timestamp_fixed; 442 // first try to add one second 443 last_timestamp_fixed = addTicks(m_last_timestamp, TICKS_PER_SECOND); 444 diff = diffTicks(last_timestamp_fixed, m_last_timestamp2); 445 if(diff-ticks_per_packet < 50 && diff-ticks_per_packet > -50) { 446 debugWarning("cy %04u rather large TSP difference TS=%011llu => TS=%011llu (%d, nom %d)\n", 447 CYCLE_TIMER_GET_CYCLES(pkt_ctr), m_last_timestamp2, 448 m_last_timestamp, diff, ticks_per_packet); 449 debugWarning("HACK: fixed by adding one second of ticks. This is a bug being run-time fixed.\n"); 450 m_last_timestamp = last_timestamp_fixed; 451 } else { 452 // if that didn't work, try to subtract one second 453 last_timestamp_fixed = substractTicks(m_last_timestamp, TICKS_PER_SECOND); 454 diff = diffTicks(last_timestamp_fixed, m_last_timestamp2); 455 if(diff-ticks_per_packet < 50 && diff-ticks_per_packet > -50) { 456 debugWarning("cy %04u rather large TSP difference TS=%011llu => TS=%011llu (%d, nom %d)\n", 457 CYCLE_TIMER_GET_CYCLES(pkt_ctr), m_last_timestamp2, 458 m_last_timestamp, diff, ticks_per_packet); 459 debugWarning("HACK: fixed by subtracing one second of ticks. This is a bug being run-time fixed.\n"); 460 m_last_timestamp = last_timestamp_fixed; 461 } 462 } 453 463 } 454 } 455 } 456 debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 457 "%04u %011llu %011llu %d %d\n", 458 CYCLE_TIMER_GET_CYCLES(pkt_ctr), 459 m_last_timestamp2, m_last_timestamp, 460 diff, ticks_per_packet); 461 // #endif 464 debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 465 "%04u %011llu %011llu %d %d\n", 466 CYCLE_TIMER_GET_CYCLES(pkt_ctr), 467 m_last_timestamp2, m_last_timestamp, 468 diff, ticks_per_packet); 469 } 470 #endif 462 471 463 472 debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, … … 723 732 debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "Nom fs: %12f, Instantanous fs: %12f, diff: %12f (%12f)\n", 724 733 fs_nom, fs_syt, fs_diff, fs_diff_norm); 734 // debugOutput(DEBUG_LEVEL_VERBOSE, "Diff fs: %12f, m_last_timestamp: %011llu, m_last_timestamp2: %011llu\n", 735 // fs_diff, m_last_timestamp, m_last_timestamp2); 725 736 if (fs_diff_norm > 0.01 || fs_diff_norm < -0.01) { 726 737 debugWarning( "Instantanous samplerate more than 1%% off nominal. [Nom fs: %12f, Instantanous fs: %12f, diff: %12f (%12f)]\n", … … 1551 1562 ringbuffer_size_frames += syncdelay_in_frames; 1552 1563 1553 debugOutput(DEBUG_LEVEL_VERBOSE, "Prefill transmit SP %p with %u frames\n", this, ringbuffer_size_frames); 1564 debugOutput(DEBUG_LEVEL_VERBOSE, "Prefill transmit SP %p with %u frames (sync_delay_frames = %d)\n", 1565 this, ringbuffer_size_frames, syncdelay_in_frames); 1554 1566 // prefill the buffer 1555 1567 if(!transferSilence(ringbuffer_size_frames)) { branches/libffado-2.0/src/libstreaming/generic/StreamProcessor.h
r1526 r1530 372 372 * @return the sync delay (in ticks) 373 373 */ 374 unsigned int getSyncDelay() {return m_sync_delay;};374 unsigned int getSyncDelay(); 375 375 unsigned int getSyncDelayFrames(); 376 376 /** 377 377 * sets the sync delay 378 * 379 * note: will be rounded to an integer number of packets 380 * 378 381 * @param d sync delay 379 382 */ 380 void setSyncDelay(unsigned int d);383 void setSyncDelay(unsigned int ticks); 381 384 382 385 /** … … 449 452 float m_ticks_per_frame; 450 453 float m_dll_bandwidth_hz; 451 unsigned int m_sync_delay ;454 unsigned int m_sync_delay_frames; 452 455 private: 453 456 bool m_in_xrun; branches/libffado-2.0/src/libstreaming/StreamProcessorManager.cpp
r1528 r1530 491 491 int max_of_min_delay = 0; 492 492 int min_delay = 0; 493 int packet_size_frames = 0; 494 int max_packet_size_frames = 0; 495 493 496 for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 494 497 it != m_ReceiveProcessors.end(); … … 496 499 min_delay = (*it)->getMaxFrameLatency(); 497 500 if(min_delay > max_of_min_delay) max_of_min_delay = min_delay; 498 } 501 packet_size_frames = (*it)->getNominalFramesPerPacket(); 502 if(packet_size_frames > max_packet_size_frames) max_packet_size_frames = packet_size_frames; 503 } 504 for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 505 it != m_TransmitProcessors.end(); 506 ++it ) { 507 packet_size_frames = (*it)->getNominalFramesPerPacket(); 508 if(packet_size_frames > max_packet_size_frames) max_packet_size_frames = packet_size_frames; 509 } 510 debugOutput( DEBUG_LEVEL_VERBOSE, " max_of_min_delay = %d, max_packet_size_frames = %d...\n", max_of_min_delay, max_packet_size_frames); 499 511 500 512 // add some processing margin. This only shifts the time 501 513 // at which the buffer is transfer()'ed. This makes things somewhat 502 // more robust. It should be noted though that shifting the transfer 503 // time to a later time instant also causes the xmit buffer fill to be 504 // lower on average. 514 // more robust. 505 515 max_of_min_delay += signal_delay_ticks; 506 516 517 // Note that the equivalent number of frames is added to the 518 // transmit buffer to ensure that it keeps a good buffer fill, no matter 519 // what the sync delay is. 507 520 m_SyncSource->setSyncDelay(max_of_min_delay); 508 521 unsigned int syncdelay = m_SyncSource->getSyncDelay(); … … 530 543 // check if we were woken up too soon 531 544 time_till_next_period = m_SyncSource->getTimeUntilNextPeriodSignalUsecs(); 532 debugOutput( DEBUG_LEVEL_VER Y_VERBOSE, "waiting for %d usecs...\n", time_till_next_period);545 debugOutput( DEBUG_LEVEL_VERBOSE, "waiting for %d usecs...\n", time_till_next_period); 533 546 if(time_till_next_period > 0) { 534 547 // wait for the period … … 549 562 } 550 563 debugOutput( DEBUG_LEVEL_VERBOSE, " sync source frame rate: %f fps (%f tpf)\n", syncrate, tpf); 564 565 m_SyncSource->setSyncDelay(max_of_min_delay); 566 syncdelay = m_SyncSource->getSyncDelay(); 567 debugOutput( DEBUG_LEVEL_VERBOSE, " updated sync delay = %d => %d ticks (%f frames) (%03us %04uc %04ut)...\n", 568 max_of_min_delay, syncdelay, syncdelay/tpf, 569 (unsigned int)TICKS_TO_SECS(syncdelay), 570 (unsigned int)TICKS_TO_CYCLES(syncdelay), 571 (unsigned int)TICKS_TO_OFFSET(syncdelay)); 551 572 552 573 // we now should have decent sync info on the sync source … … 563 584 // this is the time window we have to setup all SP's such that they 564 585 // can start wet-running correctly. 586 // we have to round this time to an integer number of audio packets 587 double time_for_startup_abs = (double)(cycles_for_startup * TICKS_PER_CYCLE); 588 int time_for_startup_frames = (int)(time_for_startup_abs / tpf); 589 time_for_startup_frames = ((time_for_startup_frames / max_packet_size_frames) + 1) * max_packet_size_frames; 590 uint64_t time_for_startup_ticks = (uint64_t)((float)time_for_startup_frames * tpf); 591 565 592 time_of_first_sample = addTicks(time_of_first_sample, 566 cycles_for_startup * TICKS_PER_CYCLE); 593 time_for_startup_ticks); 594 debugOutput( DEBUG_LEVEL_VERBOSE, " add %d frames (%011llu ticks)...\n", 595 time_for_startup_frames, time_for_startup_ticks); 567 596 568 597 debugOutput( DEBUG_LEVEL_VERBOSE, " => first sample at TS=%011llu (%03us %04uc %04ut)...\n", … … 571 600 (unsigned int)TICKS_TO_CYCLES(time_of_first_sample), 572 601 (unsigned int)TICKS_TO_OFFSET(time_of_first_sample)); 573 574 #ifdef DEBUG575 // the time at which the previous period would have passed is the576 // time of the first sample received, minus one frame.577 //m_time_of_transfer2 = substractTicks(time_of_first_sample, (uint64_t)m_SyncSource->getTicksPerFrame());578 m_time_of_transfer2 = time_of_first_sample;579 #endif580 602 581 603 // we should start wet-running the transmit SP's some cycles in advance … … 603 625 ++it ) { 604 626 (*it)->setBufferHeadTimestamp(time_of_first_sample); 627 ffado_timestamp_t ts; 628 signed int fc; 629 (*it)->getBufferHeadTimestamp ( &ts, &fc ); 630 debugOutput( DEBUG_LEVEL_VERBOSE, " transmit buffer tail %010lld => head TS %010lld, fc=%d...\n", 631 time_of_first_sample, (uint64_t)ts, fc); 605 632 } 606 633 … … 659 686 m_time_of_transfer = m_SyncSource->getTimeAtPeriod(); 660 687 661 // and a ( still veryrough) approximation of the rate688 // and a (rough) approximation of the rate 662 689 float rate = m_SyncSource->getTicksPerFrame(); 690 691 #ifdef DEBUG 692 // the time at which the previous period would have passed 693 m_time_of_transfer2 = m_time_of_transfer; 694 m_time_of_transfer2 = substractTicks(m_time_of_transfer2, (uint64_t)(m_period * rate)); 695 #endif 696 697 debugOutput( DEBUG_LEVEL_VERBOSE, " initial time of transfer %010lld, rate %f...\n", 698 m_time_of_transfer, rate); 699 663 700 int64_t delay_in_ticks = (int64_t)(((float)((m_nb_buffers-1) * m_period)) * rate); 664 701 // also add the sync delay 665 702 delay_in_ticks = addTicks(delay_in_ticks, m_SyncSource->getSyncDelay()); 666 debugOutput( DEBUG_LEVEL_VERBOSE, " initial time of transfer %010lld, rate %f...\n",667 m_time_of_transfer, rate);668 703 669 704 … … 679 714 680 715 int64_t transmit_tail_timestamp = addTicks(m_time_of_transfer, delay_in_ticks); 681 682 716 debugOutput( DEBUG_LEVEL_VERBOSE, " preset transmit tail TS %010lld, rate %f...\n", 683 717 transmit_tail_timestamp, rate); … … 686 720 it != m_TransmitProcessors.end(); 687 721 ++it ) { 722 (*it)->setTicksPerFrame(rate); 688 723 (*it)->setBufferTailTimestamp(transmit_tail_timestamp); 689 (*it)->setTicksPerFrame(rate); 724 ffado_timestamp_t ts; 725 signed int fc; 726 (*it)->getBufferHeadTimestamp ( &ts, &fc ); 727 debugOutput( DEBUG_LEVEL_VERBOSE, " => transmit head TS %010lld, fc=%d...\n", 728 (uint64_t)ts, fc); 690 729 } 691 730 branches/libffado-2.0/src/libutil/TimestampedBuffer.cpp
r1529 r1530 58 58 pthread_mutex_unlock(&m_framecounter_lock); \ 59 59 } 60 60 61 61 62 namespace Util { … … 71 72 m_wrap_at(0xFFFFFFFFFFFFFFFFLLU), 72 73 m_Client(c), m_framecounter(0), 73 m_buffer_tail_timestamp( 0.0),74 m_buffer_next_tail_timestamp( 0.0),74 m_buffer_tail_timestamp(TIMESTAMP_MAX + 1.0), 75 m_buffer_next_tail_timestamp(TIMESTAMP_MAX + 1.0), 75 76 m_dll_e2(0.0), m_dll_b(DLL_COEFF_B), m_dll_c(DLL_COEFF_C), 76 77 m_nominal_rate(0.0), m_current_rate(0.0), m_update_period(0) … … 202 203 ENTER_CRITICAL_SECTION; 203 204 204 m_dll_e2 = m_update_period * (double)rate; 205 m_current_rate = rate; 206 m_dll_e2 = m_update_period * m_current_rate; 205 207 m_buffer_next_tail_timestamp = (ffado_timestamp_t)((double)m_buffer_tail_timestamp + m_dll_e2); 206 208 … … 331 333 * 332 334 * Resets the TimestampedBuffer, clearing the buffers and counters. 333 * Also resets the DLL to the nominal values.335 * [DEL Also resets the DLL to the nominal values. DEL] 334 336 * 335 337 * \note when this is called, you should make sure that the buffer … … 344 346 345 347 m_current_rate = m_nominal_rate; 346 m_dll_e2=m_nominal_rate * (float)m_update_period; 347 // this will init the internal timestamps to a sensible value 348 setBufferTailTimestamp(m_buffer_tail_timestamp); 348 m_dll_e2 = m_current_rate * (float)m_update_period; 349 349 350 350 return true; … … 402 402 403 403 // init the DLL 404 m_dll_e2=m_nominal_rate * (float)m_update_period; 405 406 // this will init the internal timestamps to a sensible value 407 setBufferTailTimestamp(m_buffer_tail_timestamp); 404 m_dll_e2 = m_nominal_rate * (float)m_update_period; 405 406 // init the timestamps to a bogus value, as there is not 407 // really something sane to say about them 408 m_buffer_tail_timestamp = TIMESTAMP_MAX + 1.0; 409 m_buffer_next_tail_timestamp = TIMESTAMP_MAX + 1.0; 408 410 409 411 return true; … … 462 464 // while disabled, we don't update the DLL, nor do we write frames 463 465 // we just set the correct timestamp for the frames 464 incrementFrameCounter(nframes, ts); 465 decrementFrameCounter(nframes); 466 if (m_buffer_tail_timestamp < TIMESTAMP_MAX && m_buffer_next_tail_timestamp < TIMESTAMP_MAX) { 467 incrementFrameCounter(nframes, ts); 468 decrementFrameCounter(nframes); 469 } 466 470 setBufferTailTimestamp(ts); 467 471 } else { … … 502 506 return false; 503 507 } 504 508 505 509 // make sure the head timestamp remains identical 506 510 signed int fc; … … 845 849 #ifdef DEBUG 846 850 if (new_timestamp >= m_wrap_at) { 847 debugWarning("timestamp not wrapped: "TIMESTAMP_FORMAT_SPEC"\n", new_timestamp);851 debugWarning("timestamp not wrapped: "TIMESTAMP_FORMAT_SPEC"\n", new_timestamp); 848 852 } 849 853 #endif … … 854 858 855 859 // add the time 856 ts += (ffado_timestamp_t)(m_ nominal_rate * (float)m_framecounter);860 ts += (ffado_timestamp_t)(m_current_rate * (float)(m_framecounter)); 857 861 858 862 if (ts >= m_wrap_at) { … … 864 868 m_buffer_tail_timestamp = ts; 865 869 866 m_dll_e2 =m_update_period * (double)m_nominal_rate;870 m_dll_e2 = m_update_period * (double)m_current_rate; 867 871 m_buffer_next_tail_timestamp = (ffado_timestamp_t)((double)m_buffer_tail_timestamp + m_dll_e2); 868 872 … … 949 953 ffado_timestamp_t retval; 950 954 ENTER_CRITICAL_SECTION; 951 retval = getTimestampFromTail(m_framecounter -nframes);955 retval = getTimestampFromTail(m_framecounter - nframes); 952 956 EXIT_CRITICAL_SECTION; 953 957 return retval; … … 1103 1107 debugOutputShort( DEBUG_LEVEL_NORMAL, " Timestamps : head: "TIMESTAMP_FORMAT_SPEC", Tail: "TIMESTAMP_FORMAT_SPEC", Next tail: "TIMESTAMP_FORMAT_SPEC"\n", 1104 1108 ts_head, m_buffer_tail_timestamp, m_buffer_next_tail_timestamp); 1105 debugOutputShort( DEBUG_LEVEL_NORMAL, " Head - Tail : "TIMESTAMP_FORMAT_SPEC" \n", diff);1109 debugOutputShort( DEBUG_LEVEL_NORMAL, " Head - Tail : "TIMESTAMP_FORMAT_SPEC" (%f frames)\n", diff, diff/m_dll_e2*m_update_period); 1106 1110 debugOutputShort( DEBUG_LEVEL_NORMAL, " DLL Rate : %f (%f)\n", m_dll_e2, m_dll_e2/m_update_period); 1107 1111 debugOutputShort( DEBUG_LEVEL_NORMAL, " DLL Bandwidth : %10e 1/ticks (%f Hz)\n", getBandwidth(), getBandwidth() * TICKS_PER_SECOND); branches/libffado-2.0/src/libutil/TimestampedBuffer.h
r1525 r1530 31 31 //typedef float ffado_timestamp_t; 32 32 //#define TIMESTAMP_FORMAT_SPEC "%14.3f" 33 33 34 typedef double ffado_timestamp_t; 34 35 #define TIMESTAMP_FORMAT_SPEC "%14.3f" 36 #define TIMESTAMP_MAX 3145728000.0 37 35 38 // typedef int64_t ffado_timestamp_t; 36 39 // #define TIMESTAMP_FORMAT_SPEC "%012lld"