Changeset 829
- Timestamp:
- 01/07/08 14:13:42 (16 years ago)
- Files:
-
- branches/api-cleanup/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp (modified) (1 diff)
- branches/api-cleanup/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp (modified) (7 diffs)
- branches/api-cleanup/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h (modified) (2 diffs)
- branches/api-cleanup/src/libstreaming/generic/Port.cpp (modified) (1 diff)
- branches/api-cleanup/src/libstreaming/generic/StreamProcessor.cpp (modified) (5 diffs)
- branches/api-cleanup/src/libstreaming/generic/StreamProcessor.h (modified) (1 diff)
- branches/api-cleanup/src/libutil/TimestampedBuffer.cpp (modified) (15 diffs)
- branches/api-cleanup/src/libutil/TimestampedBuffer.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/api-cleanup/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp
r816 r829 416 416 sample_int |= 0x01000000; // flag that there is a midi event present 417 417 *buffer = sample_int; 418 debugOutput(DEBUG_LEVEL_VERBOSE, "Received midi byte %08X on port %p index %d\n", sample_int, p, j-location); 418 419 } 419 420 buffer += 8; // skip 8 frames branches/api-cleanup/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp
r818 r829 57 57 int cycle, unsigned int dropped, unsigned int max_length ) 58 58 { 59 struct iec61883_packet *packet = ( struct iec61883_packet * ) data; 59 __builtin_prefetch(data, 1, 0); // prefetch events for write, no temporal locality 60 struct iec61883_packet *packet = (struct iec61883_packet *)data; 60 61 /* Our node ID can change after a bus reset, so it is best to fetch 61 62 * our node ID for each packet. */ 62 packet->sid = m_ 1394service.getLocalNodeId() & 0x3f;63 packet->sid = m_local_node_id; 63 64 64 65 packet->dbs = m_dimension; … … 275 276 /* Our node ID can change after a bus reset, so it is best to fetch 276 277 * our node ID for each packet. */ 277 packet->sid = m_ 1394service.getLocalNodeId() & 0x3f;278 packet->sid = m_local_node_id; 278 279 279 280 packet->dbs = m_dimension; … … 480 481 assert(nevents + offset <= p.buffer_size ); 481 482 482 float *buffer = (float *)(p.buffer); 483 buffer += offset; 484 __builtin_prefetch(buffer, 0, 0); // prefetch events for read, no temporal locality 485 486 for (j = 0;j < nevents; j += 1) 487 { 488 // don't care for overflow 489 float v = (*buffer) * AMDTP_FLOAT_MULTIPLIER; 490 unsigned int tmp = ((int) v); 491 *target_event = htonl ( ( tmp >> 8 ) | 0x40000000 ); 492 buffer++; 483 if(p.buffer && p.enabled) { 484 float *buffer = (float *)(p.buffer); 485 buffer += offset; 493 486 __builtin_prefetch(buffer, 0, 0); // prefetch events for read, no temporal locality 494 target_event += m_dimension; 495 __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 487 488 for (j = 0;j < nevents; j += 1) 489 { 490 // don't care for overflow 491 float v = (*buffer) * AMDTP_FLOAT_MULTIPLIER; 492 unsigned int tmp = ((int) v); 493 *target_event = htonl ( ( tmp >> 8 ) | 0x40000000 ); 494 buffer++; 495 __builtin_prefetch(buffer, 0, 0); // prefetch events for read, no temporal locality 496 target_event += m_dimension; 497 __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 498 } 499 } else { 500 for (j = 0;j < nevents; j += 1) 501 { 502 *target_event = htonl( 0x40000000 ); 503 target_event += m_dimension; 504 __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 505 } 496 506 } 497 507 } … … 519 529 assert(nevents + offset <= p.buffer_size ); 520 530 521 uint32_t *buffer = (uint32_t *)(p.buffer); 522 buffer += offset; 523 __builtin_prefetch(buffer, 0, 0); // prefetch events for read, no temporal locality 524 525 for (j = 0; j < nevents; j += 1) 526 { 527 *target_event = htonl(((*buffer) & 0x00FFFFFF) | 0x40000000); 528 buffer++; 531 if(p.buffer && p.enabled) { 532 uint32_t *buffer = (uint32_t *)(p.buffer); 533 buffer += offset; 529 534 __builtin_prefetch(buffer, 0, 0); // prefetch events for read, no temporal locality 530 535 531 target_event += m_dimension; 532 __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 536 for (j = 0; j < nevents; j += 1) 537 { 538 *target_event = htonl(((*buffer) & 0x00FFFFFF) | 0x40000000); 539 buffer++; 540 __builtin_prefetch(buffer, 0, 0); // prefetch events for read, no temporal locality 541 542 target_event += m_dimension; 543 __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 544 } 545 } else { 546 for (j = 0;j < nevents; j += 1) 547 { 548 *target_event = htonl( 0x40000000 ); 549 target_event += m_dimension; 550 __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 551 } 533 552 } 534 553 } … … 576 595 for (i = 0; i < m_nb_midi_ports; i++) { 577 596 struct _MIDI_port_cache &p = m_midi_ports.at(i); 578 uint32_t *buffer = (quadlet_t *)(p.buffer); 579 buffer += offset; 580 __builtin_prefetch(buffer, 0, 0); // prefetch events for read, no temporal locality 581 582 for (j = p.location;j < nevents; j += 8) { 583 target_event = (quadlet_t *) (data + ((j * m_dimension) + p.position)); 584 __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 585 586 if ( *buffer & 0xFF000000 ) // we can send a byte 587 { 588 quadlet_t tmpval; 589 tmpval = ((*buffer)<<16) & 0x00FF0000; 590 tmpval = IEC61883_AM824_SET_LABEL(tmpval, IEC61883_AM824_LABEL_MIDI_1X); 591 *target_event = htonl(tmpval); 597 if (p.buffer && p.enabled) { 598 uint32_t *buffer = (quadlet_t *)(p.buffer); 599 buffer += offset; 600 __builtin_prefetch(buffer, 0, 0); // prefetch events for read, no temporal locality 592 601 593 // debugOutput ( DEBUG_LEVEL_VERBOSE, "MIDI port %s, pos=%u, loc=%u, nevents=%u, dim=%d\n", 594 // p->getName().c_str(), position, location, nevents, m_dimension ); 595 // debugOutput ( DEBUG_LEVEL_VERBOSE, "base=%p, target=%p, value=%08X\n", 596 // data, target_event, tmpval ); 597 } else { 598 // can't send a byte, either because there is no byte, 599 // or because this would exceed the maximum rate 600 // FIXME: this can be ifdef optimized since it's a constant 602 for (j = p.location;j < nevents; j += 8) { 603 target_event = (quadlet_t *) (data + ((j * m_dimension) + p.position)); 604 __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 605 606 if ( *buffer & 0xFF000000 ) // we can send a byte 607 { 608 quadlet_t tmpval; 609 tmpval = ((*buffer)<<16) & 0x00FF0000; 610 tmpval = IEC61883_AM824_SET_LABEL(tmpval, IEC61883_AM824_LABEL_MIDI_1X); 611 *target_event = htonl(tmpval); 612 613 // debugOutput ( DEBUG_LEVEL_VERBOSE, "MIDI port %s, pos=%u, loc=%u, nevents=%u, dim=%d\n", 614 // p.port->getName().c_str(), p.position, p.location, nevents, m_dimension ); 615 // debugOutput ( DEBUG_LEVEL_VERBOSE, "base=%p, target=%p, value=%08X\n", 616 // data, target_event, tmpval ); 617 } else { 618 // can't send a byte, either because there is no byte, 619 // or because this would exceed the maximum rate 620 // FIXME: this can be ifdef optimized since it's a constant 621 *target_event = htonl(IEC61883_AM824_SET_LABEL(0, IEC61883_AM824_LABEL_MIDI_NO_DATA)); 622 } 623 buffer+=8; 624 } 625 } else { 626 for (j = p.location;j < nevents; j += 8) { 627 target_event = (quadlet_t *) (data + ((j * m_dimension) + p.position)); 628 __builtin_prefetch(target_event, 1, 0); // prefetch events for write, no temporal locality 601 629 *target_event = htonl(IEC61883_AM824_SET_LABEL(0, IEC61883_AM824_LABEL_MIDI_NO_DATA)); 602 630 } 603 buffer+=8;604 631 } 605 632 } … … 712 739 AmdtpAudioPort *port = p.port; 713 740 p.buffer = port->getBufferAddress(); 741 p.enabled = !port->isDisabled(); 714 742 } 715 743 for (idx = 0; idx < m_nb_midi_ports; idx++) { … … 717 745 AmdtpMidiPort *port = p.port; 718 746 p.buffer = port->getBufferAddress(); 747 p.enabled = !port->isDisabled(); 719 748 } 720 749 } branches/api-cleanup/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h
r817 r829 134 134 AmdtpAudioPort* port; 135 135 void* buffer; 136 bool enabled; 136 137 #ifdef DEBUG 137 138 unsigned int buffer_size; … … 144 145 AmdtpMidiPort* port; 145 146 void* buffer; 147 bool enabled; 146 148 unsigned int position; 147 149 unsigned int location; branches/api-cleanup/src/libstreaming/generic/Port.cpp
r816 r829 67 67 if (m_buffersize == 0) { 68 68 debugFatal("Cannot initialize a port with buffersize=0\n"); 69 return false;70 }71 72 if (m_buffer == NULL) {73 debugFatal("Cannot initialize a port with no attached buffer\n");74 69 return false; 75 70 } branches/api-cleanup/src/libstreaming/generic/StreamProcessor.cpp
r821 r829 66 66 , m_IsoHandlerManager( parent.get1394Service().getIsoHandlerManager() ) // local cache 67 67 , m_StreamProcessorManager( m_Parent.getDeviceManager().getStreamProcessorManager() ) // local cache 68 , m_local_node_id ( 0 ) // local cache 68 69 , m_channel( -1 ) 69 70 , m_dropped(0) … … 935 936 if(m_state != ePS_Running || m_next_state != ePS_Running) return true; 936 937 bool result; 937 int bufferfill;938 unsigned int bufferfill; 938 939 if(getType() == ePT_Receive) { 939 940 bufferfill = m_data_buffer->getBufferSpace(); … … 1324 1325 ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_StreamProcessorManager.getNominalRate()); 1325 1326 m_ticks_per_frame = ticks_per_frame; 1327 m_local_node_id= m_1394service.getLocalNodeId() & 0x3f; 1328 1326 1329 debugOutput(DEBUG_LEVEL_VERBOSE,"Initializing remote ticks/frame to %f\n", ticks_per_frame); 1327 1330 … … 1420 1423 // a running stream has been detected 1421 1424 debugOutput(DEBUG_LEVEL_VERBOSE, "StreamProcessor %p started dry-running at cycle %d\n", this, m_last_cycle); 1425 m_local_node_id = m_1394service.getLocalNodeId() & 0x3f; 1422 1426 if (getType() == ePT_Receive) { 1423 1427 // this to ensure that there is no discontinuity when starting to … … 1526 1530 this, m_last_cycle); 1527 1531 m_in_xrun = false; 1532 m_local_node_id = m_1394service.getLocalNodeId() & 0x3f; 1528 1533 m_data_buffer->setTransparent(false); 1529 1534 break; branches/api-cleanup/src/libstreaming/generic/StreamProcessor.h
r809 r829 137 137 IsoHandlerManager& m_IsoHandlerManager; 138 138 StreamProcessorManager& m_StreamProcessorManager; 139 unsigned int m_local_node_id; 139 140 140 141 public: // the public receive/transmit functions branches/api-cleanup/src/libutil/TimestampedBuffer.cpp
r813 r829 38 38 #define DLL_COEFF_C (DLL_OMEGA * DLL_OMEGA) 39 39 40 #define FRAMES_PER_PROCESS_BLOCK 8 40 41 /* 41 42 #define ENTER_CRITICAL_SECTION { \ … … 58 59 59 60 TimestampedBuffer::TimestampedBuffer(TimestampedBufferClient *c) 60 : m_event_buffer(NULL), m_cluster_buffer(NULL), 61 : m_event_buffer(NULL), m_process_buffer(NULL), m_cluster_size( 0 ), 62 m_process_block_size( 0 ), 61 63 m_event_size(0), m_events_per_frame(0), m_buffer_size(0), 62 64 m_bytes_per_frame(0), m_bytes_per_buffer(0), … … 75 77 TimestampedBuffer::~TimestampedBuffer() { 76 78 ffado_ringbuffer_free(m_event_buffer); 77 free(m_ cluster_buffer);79 free(m_process_buffer); 78 80 } 79 81 … … 334 336 335 337 // allocate the temporary cluster buffer 336 if( !(m_cluster_buffer=(char *)calloc(m_events_per_frame,m_event_size))) { 338 // NOTE: has to be a multiple of 8 in order to 339 // correctly decode midi bytes (since that 340 // enforces packet alignment) 341 m_cluster_size = m_events_per_frame * m_event_size; 342 m_process_block_size = m_cluster_size * FRAMES_PER_PROCESS_BLOCK; 343 if( !(m_process_buffer=(char *)calloc(m_process_block_size, 1))) { 337 344 debugFatal("Could not allocate temporary cluster buffer\n"); 338 345 ffado_ringbuffer_free(m_event_buffer); … … 523 530 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n"); 524 531 int xrun; 525 unsigned int offset =0;532 unsigned int offset = 0; 526 533 527 534 ffado_ringbuffer_data_t vec[2]; 528 535 // we received one period of frames 529 536 // this is period_size*dimension of events 530 unsigned int events2write =nbframes*m_events_per_frame;531 unsigned int bytes2write =events2write*m_event_size;537 unsigned int events2write = nbframes * m_events_per_frame; 538 unsigned int bytes2write = events2write * m_event_size; 532 539 533 540 /* write events2write bytes to the ringbuffer … … 539 546 * Make sure that we cannot end up on a non-cluster aligned position! 540 547 */ 541 unsigned int cluster_size=m_events_per_frame*m_event_size; 542 543 while(bytes2write>0) { 544 int byteswritten=0; 545 546 unsigned int frameswritten=(nbframes*cluster_size-bytes2write)/cluster_size; 547 offset=frameswritten; 548 549 while(bytes2write > 0) { 550 int byteswritten = 0; 551 552 unsigned int frameswritten = (nbframes * m_cluster_size - bytes2write) / m_cluster_size; 553 offset = frameswritten; 548 554 549 555 ffado_ringbuffer_get_write_vector(m_event_buffer, vec); 550 556 551 if(vec[0].len ==0) { // this indicates a full event buffer557 if(vec[0].len + vec[1].len < m_process_block_size) { // this indicates a full event buffer 552 558 debugError("Event buffer overrun in buffer %p, fill: %u, bytes2write: %u \n", 553 559 this, ffado_ringbuffer_read_space(m_event_buffer), bytes2write); … … 562 568 * this can happen because the ringbuffer size is always a power of 2 563 569 */ 564 if(vec[0].len <cluster_size) {570 if(vec[0].len < m_process_block_size) { 565 571 566 572 // encode to the temporary buffer 567 xrun = m_Client->processWriteBlock(m_cluster_buffer, 1, offset); 568 569 if(xrun<0) { 573 // note that we always process 8 frames at once, in order to ensure that 574 // we don't have to care about the DBC field 575 xrun = m_Client->processWriteBlock(m_process_buffer, FRAMES_PER_PROCESS_BLOCK, offset); 576 577 if(xrun < 0) { 570 578 // xrun detected 571 579 debugError("Frame buffer underrun in buffer %p\n",this); … … 576 584 // the write function handles the wrap around. 577 585 ffado_ringbuffer_write(m_event_buffer, 578 m_cluster_buffer,579 cluster_size);586 m_process_buffer, 587 m_process_block_size); 580 588 581 589 // we advanced one cluster_size 582 bytes2write -=cluster_size;590 bytes2write -= m_process_block_size; 583 591 584 592 } else { // 585 593 586 if(bytes2write >vec[0].len) {594 if(bytes2write > vec[0].len) { 587 595 // align to a cluster boundary 588 byteswritten =vec[0].len-(vec[0].len%cluster_size);596 byteswritten = vec[0].len - (vec[0].len % m_process_block_size); 589 597 } else { 590 byteswritten =bytes2write;598 byteswritten = bytes2write; 591 599 } 592 600 593 601 xrun = m_Client->processWriteBlock(vec[0].buf, 594 byteswritten/cluster_size,595 offset);596 597 if(xrun <0) {598 602 byteswritten / m_cluster_size, 603 offset); 604 605 if(xrun < 0 ) { 606 // xrun detected 599 607 debugError("Frame buffer underrun in buffer %p\n",this); 600 608 return false; // FIXME: return false ? … … 605 613 } 606 614 607 // the bytes2write should always be clusteraligned608 assert(bytes2write %cluster_size==0);615 // the bytes2write should always be process block aligned 616 assert(bytes2write % m_process_block_size == 0); 609 617 610 618 } … … 632 640 633 641 int xrun; 634 unsigned int offset =0;642 unsigned int offset = 0; 635 643 636 644 ffado_ringbuffer_data_t vec[2]; … … 638 646 // this is period_size*dimension of events 639 647 640 unsigned int events2read =nbframes*m_events_per_frame;641 unsigned int bytes2read =events2read*m_event_size;648 unsigned int events2read = nbframes * m_events_per_frame; 649 unsigned int bytes2read = events2read * m_event_size; 642 650 /* read events2read bytes from the ringbuffer 643 651 * first see if it can be done in one read. … … 648 656 * Make sure that we cannot end up on a non-cluster aligned position! 649 657 */ 650 unsigned int cluster_size=m_events_per_frame*m_event_size; 651 652 while(bytes2read>0) { 653 unsigned int framesread=(nbframes*cluster_size-bytes2read)/cluster_size; 654 offset=framesread; 655 656 int bytesread=0; 658 659 while(bytes2read > 0) { 660 unsigned int framesread = (nbframes * m_cluster_size - bytes2read) / m_cluster_size; 661 offset = framesread; 662 663 int bytesread = 0; 657 664 658 665 ffado_ringbuffer_get_read_vector(m_event_buffer, vec); 659 666 660 if(vec[0].len ==0) { // this indicates an empty event buffer667 if(vec[0].len + vec[1].len < m_process_block_size) { // this indicates an empty event buffer 661 668 debugError("Event buffer underrun in buffer %p\n",this); 662 669 return false; … … 668 675 * this can happen because the ringbuffer size is always a power of 2 669 676 */ 670 if(vec[0].len <cluster_size) {677 if(vec[0].len < m_process_block_size) { 671 678 // use the ringbuffer function to read one cluster 672 679 // the read function handles wrap around 673 ffado_ringbuffer_read(m_event_buffer, m_cluster_buffer,cluster_size);680 ffado_ringbuffer_read(m_event_buffer, m_process_buffer, m_process_block_size); 674 681 675 682 assert(m_Client); 676 xrun = m_Client->processReadBlock(m_cluster_buffer, 1, offset); 677 678 if(xrun<0) { 683 // note that we always process 8 frames at once, in order to ensure that 684 // we don't have to care about the DBC field 685 xrun = m_Client->processReadBlock(m_process_buffer, FRAMES_PER_PROCESS_BLOCK, offset); 686 687 if(xrun < 0) { 679 688 // xrun detected 680 689 debugError("Frame buffer overrun in buffer %p\n",this); … … 683 692 684 693 // we advanced one cluster_size 685 bytes2read -=cluster_size;694 bytes2read -= m_process_block_size; 686 695 687 696 } else { // 688 697 689 if(bytes2read >vec[0].len) {698 if(bytes2read > vec[0].len) { 690 699 // align to a cluster boundary 691 bytesread =vec[0].len-(vec[0].len%cluster_size);700 bytesread = vec[0].len - (vec[0].len % m_process_block_size); 692 701 } else { 693 bytesread =bytes2read;702 bytesread = bytes2read; 694 703 } 695 704 696 705 assert(m_Client); 697 xrun = m_Client->processReadBlock(vec[0].buf, bytesread/ cluster_size, offset);698 699 if(xrun <0) {706 xrun = m_Client->processReadBlock(vec[0].buf, bytesread/m_cluster_size, offset); 707 708 if(xrun < 0) { 700 709 // xrun detected 701 710 debugError("Frame buffer overrun in buffer %p\n",this); … … 708 717 709 718 // the bytes2read should always be cluster aligned 710 assert(bytes2read %cluster_size==0);719 assert(bytes2read % m_process_block_size == 0); 711 720 } 712 721 branches/api-cleanup/src/libutil/TimestampedBuffer.h
r813 r829 166 166 167 167 ffado_ringbuffer_t * m_event_buffer; 168 char* m_cluster_buffer; 168 char* m_process_buffer; 169 unsigned int m_cluster_size; 170 unsigned int m_process_block_size; 169 171 170 172 unsigned int m_event_size; // the size of one event