Changeset 829

Show
Ignore:
Timestamp:
01/07/08 14:13:42 (14 years ago)
Author:
ppalmers
Message:

some caching and bugfixes

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/api-cleanup/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp

    r816 r829  
    416416            sample_int |= 0x01000000; // flag that there is a midi event present 
    417417            *buffer = sample_int; 
     418            debugOutput(DEBUG_LEVEL_VERBOSE, "Received midi byte %08X on port %p index %d\n", sample_int, p, j-location); 
    418419        } 
    419420        buffer += 8; // skip 8 frames 
  • branches/api-cleanup/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp

    r818 r829  
    5757    int cycle, unsigned int dropped, unsigned int max_length ) 
    5858{ 
    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; 
    6061    /* Our node ID can change after a bus reset, so it is best to fetch 
    6162    * our node ID for each packet. */ 
    62     packet->sid = m_1394service.getLocalNodeId() & 0x3f
     63    packet->sid = m_local_node_id
    6364 
    6465    packet->dbs = m_dimension; 
     
    275276    /* Our node ID can change after a bus reset, so it is best to fetch 
    276277    * our node ID for each packet. */ 
    277     packet->sid = m_1394service.getLocalNodeId() & 0x3f
     278    packet->sid = m_local_node_id
    278279 
    279280    packet->dbs = m_dimension; 
     
    480481        assert(nevents + offset <= p.buffer_size ); 
    481482 
    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; 
    493486            __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            } 
    496506        } 
    497507    } 
     
    519529        assert(nevents + offset <= p.buffer_size ); 
    520530 
    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; 
    529534            __builtin_prefetch(buffer, 0, 0); // prefetch events for read, no temporal locality 
    530535 
    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            } 
    533552        } 
    534553    } 
     
    576595    for (i = 0; i < m_nb_midi_ports; i++) { 
    577596        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 
    592601     
    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 
    601629                *target_event = htonl(IEC61883_AM824_SET_LABEL(0, IEC61883_AM824_LABEL_MIDI_NO_DATA)); 
    602630            } 
    603             buffer+=8; 
    604631        } 
    605632    } 
     
    712739        AmdtpAudioPort *port = p.port; 
    713740        p.buffer = port->getBufferAddress(); 
     741        p.enabled = !port->isDisabled(); 
    714742    } 
    715743    for (idx = 0; idx < m_nb_midi_ports; idx++) { 
     
    717745        AmdtpMidiPort *port = p.port; 
    718746        p.buffer = port->getBufferAddress(); 
     747        p.enabled = !port->isDisabled(); 
    719748    } 
    720749} 
  • branches/api-cleanup/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h

    r817 r829  
    134134        AmdtpAudioPort*     port; 
    135135        void*               buffer; 
     136        bool                enabled; 
    136137#ifdef DEBUG 
    137138        unsigned int        buffer_size; 
     
    144145        AmdtpMidiPort*      port; 
    145146        void*               buffer; 
     147        bool                enabled; 
    146148        unsigned int        position; 
    147149        unsigned int        location; 
  • branches/api-cleanup/src/libstreaming/generic/Port.cpp

    r816 r829  
    6767    if (m_buffersize == 0) { 
    6868        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"); 
    7469        return false; 
    7570    } 
  • branches/api-cleanup/src/libstreaming/generic/StreamProcessor.cpp

    r821 r829  
    6666    , m_IsoHandlerManager( parent.get1394Service().getIsoHandlerManager() ) // local cache 
    6767    , m_StreamProcessorManager( m_Parent.getDeviceManager().getStreamProcessorManager() ) // local cache 
     68    , m_local_node_id ( 0 ) // local cache 
    6869    , m_channel( -1 ) 
    6970    , m_dropped(0) 
     
    935936    if(m_state != ePS_Running || m_next_state != ePS_Running) return true; 
    936937    bool result; 
    937     int bufferfill; 
     938    unsigned int bufferfill; 
    938939    if(getType() == ePT_Receive) { 
    939940        bufferfill = m_data_buffer->getBufferSpace(); 
     
    13241325            ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_StreamProcessorManager.getNominalRate()); 
    13251326            m_ticks_per_frame = ticks_per_frame; 
     1327            m_local_node_id= m_1394service.getLocalNodeId() & 0x3f; 
     1328 
    13261329            debugOutput(DEBUG_LEVEL_VERBOSE,"Initializing remote ticks/frame to %f\n", ticks_per_frame); 
    13271330 
     
    14201423            // a running stream has been detected 
    14211424            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; 
    14221426            if (getType() == ePT_Receive) { 
    14231427                // this to ensure that there is no discontinuity when starting to  
     
    15261530                                             this, m_last_cycle); 
    15271531            m_in_xrun = false; 
     1532            m_local_node_id = m_1394service.getLocalNodeId() & 0x3f; 
    15281533            m_data_buffer->setTransparent(false); 
    15291534            break; 
  • branches/api-cleanup/src/libstreaming/generic/StreamProcessor.h

    r809 r829  
    137137    IsoHandlerManager&          m_IsoHandlerManager; 
    138138    StreamProcessorManager&     m_StreamProcessorManager; 
     139    unsigned int                m_local_node_id; 
    139140 
    140141public: // the public receive/transmit functions 
  • branches/api-cleanup/src/libutil/TimestampedBuffer.cpp

    r813 r829  
    3838#define DLL_COEFF_C   (DLL_OMEGA * DLL_OMEGA) 
    3939 
     40#define FRAMES_PER_PROCESS_BLOCK 8 
    4041/* 
    4142#define ENTER_CRITICAL_SECTION { \ 
     
    5859 
    5960TimestampedBuffer::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 ), 
    6163      m_event_size(0), m_events_per_frame(0), m_buffer_size(0), 
    6264      m_bytes_per_frame(0), m_bytes_per_buffer(0), 
     
    7577TimestampedBuffer::~TimestampedBuffer() { 
    7678    ffado_ringbuffer_free(m_event_buffer); 
    77     free(m_cluster_buffer); 
     79    free(m_process_buffer); 
    7880} 
    7981 
     
    334336 
    335337    // 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))) { 
    337344            debugFatal("Could not allocate temporary cluster buffer\n"); 
    338345        ffado_ringbuffer_free(m_event_buffer); 
     
    523530    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n"); 
    524531    int xrun; 
    525     unsigned int offset=0; 
     532    unsigned int offset = 0; 
    526533 
    527534    ffado_ringbuffer_data_t vec[2]; 
    528535    // we received one period of frames 
    529536    // 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; 
    532539 
    533540    /* write events2write bytes to the ringbuffer 
     
    539546    *  Make sure that we cannot end up on a non-cluster aligned position! 
    540547    */ 
    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; 
    548554 
    549555        ffado_ringbuffer_get_write_vector(m_event_buffer, vec); 
    550556 
    551         if(vec[0].len==0) { // this indicates a full event buffer 
     557        if(vec[0].len + vec[1].len < m_process_block_size) { // this indicates a full event buffer 
    552558            debugError("Event buffer overrun in buffer %p, fill: %u, bytes2write: %u \n", 
    553559                       this, ffado_ringbuffer_read_space(m_event_buffer), bytes2write); 
     
    562568        * this can happen because the ringbuffer size is always a power of 2 
    563569        */ 
    564         if(vec[0].len<cluster_size) { 
     570        if(vec[0].len < m_process_block_size) { 
    565571 
    566572            // 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) { 
    570578                // xrun detected 
    571579                debugError("Frame buffer underrun in buffer %p\n",this); 
     
    576584            // the write function handles the wrap around. 
    577585            ffado_ringbuffer_write(m_event_buffer, 
    578                          m_cluster_buffer, 
    579                          cluster_size); 
     586                                   m_process_buffer, 
     587                                   m_process_block_size); 
    580588 
    581589            // we advanced one cluster_size 
    582             bytes2write-=cluster_size; 
     590            bytes2write -= m_process_block_size; 
    583591 
    584592        } else { // 
    585593 
    586             if(bytes2write>vec[0].len) { 
     594            if(bytes2write > vec[0].len) { 
    587595                // 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); 
    589597            } else { 
    590                 byteswritten=bytes2write; 
     598                byteswritten = bytes2write; 
    591599            } 
    592600 
    593601            xrun = m_Client->processWriteBlock(vec[0].buf, 
    594                          byteswritten/cluster_size, 
    595                          offset); 
    596  
    597             if(xrun<0) { 
    598                     // xrun detected 
     602                                               byteswritten / m_cluster_size, 
     603                                               offset); 
     604 
     605            if(xrun < 0 ) { 
     606                // xrun detected 
    599607                debugError("Frame buffer underrun in buffer %p\n",this); 
    600608                return false; // FIXME: return false ? 
     
    605613        } 
    606614 
    607         // the bytes2write should always be cluster aligned 
    608         assert(bytes2write%cluster_size==0); 
     615        // the bytes2write should always be process block aligned 
     616        assert(bytes2write % m_process_block_size == 0); 
    609617 
    610618    } 
     
    632640 
    633641    int xrun; 
    634     unsigned int offset=0; 
     642    unsigned int offset = 0; 
    635643 
    636644    ffado_ringbuffer_data_t vec[2]; 
     
    638646    // this is period_size*dimension of events 
    639647 
    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; 
    642650    /* read events2read bytes from the ringbuffer 
    643651    *  first see if it can be done in one read. 
     
    648656    *  Make sure that we cannot end up on a non-cluster aligned position! 
    649657    */ 
    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; 
    657664 
    658665        ffado_ringbuffer_get_read_vector(m_event_buffer, vec); 
    659666 
    660         if(vec[0].len==0) { // this indicates an empty event buffer 
     667        if(vec[0].len + vec[1].len < m_process_block_size) { // this indicates an empty event buffer 
    661668            debugError("Event buffer underrun in buffer %p\n",this); 
    662669            return false; 
     
    668675        * this can happen because the ringbuffer size is always a power of 2 
    669676                */ 
    670         if(vec[0].len<cluster_size) { 
     677        if(vec[0].len < m_process_block_size) { 
    671678            // use the ringbuffer function to read one cluster 
    672679            // 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); 
    674681 
    675682            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) { 
    679688                // xrun detected 
    680689                debugError("Frame buffer overrun in buffer %p\n",this); 
     
    683692 
    684693            // we advanced one cluster_size 
    685             bytes2read-=cluster_size; 
     694            bytes2read -= m_process_block_size; 
    686695 
    687696        } else { // 
    688697 
    689             if(bytes2read>vec[0].len) { 
     698            if(bytes2read > vec[0].len) { 
    690699                // 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); 
    692701            } else { 
    693                 bytesread=bytes2read; 
     702                bytesread = bytes2read; 
    694703            } 
    695704 
    696705            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) { 
    700709                // xrun detected 
    701710                debugError("Frame buffer overrun in buffer %p\n",this); 
     
    708717 
    709718        // the bytes2read should always be cluster aligned 
    710         assert(bytes2read%cluster_size==0); 
     719        assert(bytes2read % m_process_block_size == 0); 
    711720    } 
    712721 
  • branches/api-cleanup/src/libutil/TimestampedBuffer.h

    r813 r829  
    166166 
    167167        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; 
    169171 
    170172        unsigned int m_event_size; // the size of one event