Show
Ignore:
Timestamp:
01/06/08 05:08:10 (16 years ago)
Author:
ppalmers
Message:

more performance fixes for the AMDTP transmit handler

Files:

Legend:

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

    r816 r817  
    406406        unsigned int nevents, unsigned int offset ) 
    407407{ 
    408     bool no_problem = true; 
    409408    updatePortCache(); 
    410  
    411     if(!encodeAudioPorts((quadlet_t *)data, offset, nevents)) { 
    412         debugError("Could not encode audio ports\n"); 
    413         return false; 
    414     } 
    415  
    416 //     for ( PortVectorIterator it = m_Ports.begin(); 
    417 //           it != m_Ports.end(); 
    418 //           ++it ) 
    419 //     { 
    420 //         if ( (*it)->isDisabled() ) { continue; }; 
    421 //  
    422 //         //FIXME: make this into a static_cast when not DEBUG? 
    423 //         AmdtpPortInfo *pinfo = dynamic_cast<AmdtpPortInfo *> ( *it ); 
    424 //         assert ( pinfo ); // this should not fail!! 
    425 //  
    426 //         switch( pinfo->getFormat() ) 
    427 //         { 
    428 //             case AmdtpPortInfo::E_MBLA: 
    429 //                 if( encodePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents) ) 
    430 //                 { 
    431 //                     debugWarning ( "Could not encode port %s to MBLA events", (*it)->getName().c_str() ); 
    432 //                     no_problem = false; 
    433 //                 } 
    434 //                 break; 
    435 //             case AmdtpPortInfo::E_SPDIF: // still unimplemented 
    436 //                 break; 
    437 //             case AmdtpPortInfo::E_Midi: 
    438 //                 if( encodePortToMidiEvents(static_cast<AmdtpMidiPort *>(*it), (quadlet_t *)data, offset, nevents) ) 
    439 //                 { 
    440 //                     debugWarning ( "Could not encode port %s to Midi events", (*it)->getName().c_str() ); 
    441 //                     no_problem = false; 
    442 //                 } 
    443 //                 break; 
    444 //             default: // ignore 
    445 //                 break; 
    446 //         } 
    447 //     } 
    448     return no_problem; 
     409    switch(m_StreamProcessorManager.getAudioDataType()) { 
     410        case StreamProcessorManager::eADT_Int24: 
     411            encodeAudioPortsInt24((quadlet_t *)data, offset, nevents); 
     412            break; 
     413        case StreamProcessorManager::eADT_Float: 
     414            encodeAudioPortsFloat((quadlet_t *)data, offset, nevents); 
     415            break; 
     416    } 
     417    encodeMidiPorts((quadlet_t *)data, offset, nevents); 
     418    return true; 
    449419} 
    450420 
     
    453423    char *data, unsigned int nevents, unsigned int offset) 
    454424{ 
    455     bool no_problem = true; 
    456     for(PortVectorIterator it = m_Ports.begin(); 
    457         it != m_Ports.end(); 
    458         ++it ) 
    459     { 
    460         //FIXME: make this into a static_cast when not DEBUG? 
    461         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it); 
    462         assert(pinfo); // this should not fail!! 
    463  
    464         switch( pinfo->getFormat() ) 
    465         { 
    466             case AmdtpPortInfo::E_MBLA: 
    467                 if ( encodeSilencePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents) ) 
    468                 { 
    469                     debugWarning("Could not encode silence for port %s to MBLA events", (*it)->getName().c_str()); 
    470                     no_problem = false; 
    471                 } 
    472                 break; 
    473             case AmdtpPortInfo::E_SPDIF: // still unimplemented 
    474                 break; 
    475             case AmdtpPortInfo::E_Midi: 
    476                 if( encodeSilencePortToMidiEvents(static_cast<AmdtpMidiPort *>(*it), (quadlet_t *)data, offset, nevents) ) 
    477                 { 
    478                     debugWarning ( "Could not encode silence for port %s to Midi events", (*it)->getName().c_str() ); 
    479                     no_problem = false; 
    480                 } 
    481                 break; 
    482             default: // ignore 
    483                 break; 
    484         } 
    485     } 
    486     return no_problem; 
    487 
    488  
    489 int AmdtpTransmitStreamProcessor::encodePortToMBLAEvents ( AmdtpAudioPort *p, quadlet_t *data, 
    490         unsigned int offset, unsigned int nevents ) 
    491 
    492     unsigned int j=0; 
    493  
    494     quadlet_t *target_event; 
    495  
    496     target_event= ( quadlet_t * ) ( data + p->getPosition() ); 
    497  
    498     switch ( m_StreamProcessorManager.getAudioDataType() ) 
    499     { 
    500         default: 
    501             debugError("bad type: %d\n", m_StreamProcessorManager.getAudioDataType()); 
    502             return -1; 
    503         case StreamProcessorManager::eADT_Int24: 
    504         { 
    505             quadlet_t *buffer= ( quadlet_t * ) ( p->getBufferAddress() ); 
    506  
    507             assert ( nevents + offset <= p->getBufferSize() ); 
    508  
    509             buffer+=offset; 
    510  
    511             for ( j = 0; j < nevents; j += 1 )   // decode max nsamples 
    512             { 
    513                 *target_event = htonl ( ( * ( buffer ) & 0x00FFFFFF ) | 0x40000000 ); 
    514                 buffer++; 
    515                 target_event += m_dimension; 
    516             } 
    517         } 
    518         break; 
    519         case StreamProcessorManager::eADT_Float: 
    520         { 
    521             float *buffer= ( float * ) ( p->getBufferAddress() ); 
    522  
    523             assert ( nevents + offset <= p->getBufferSize() ); 
    524  
    525             buffer+=offset; 
    526  
    527             for ( j = 0; j < nevents; j += 1 )   // decode max nsamples 
    528             { 
    529  
    530                 // don't care for overflow 
    531                 float v = *buffer * AMDTP_FLOAT_MULTIPLIER;  // v: -231 .. 231 
    532                 unsigned int tmp = ( ( int ) v ); 
    533                 *target_event = htonl ( ( tmp >> 8 ) | 0x40000000 ); 
    534  
    535                 buffer++; 
    536                 target_event += m_dimension; 
    537             } 
    538         } 
    539         break; 
    540     } 
    541  
    542     return 0; 
    543 
    544  
    545 // note: make sure that the midi events in the port buffer are only placed on (buffer+offset+x)%8 == 0 
    546 // i.e. 8 frame aligned 
    547 int AmdtpTransmitStreamProcessor::encodePortToMidiEvents ( AmdtpMidiPort *p, quadlet_t *data, 
    548         unsigned int offset, unsigned int nevents ) 
    549 
    550     unsigned int j=0; 
    551     unsigned int position = p->getPosition(); 
    552     unsigned int location = p->getLocation(); 
    553  
    554     quadlet_t *target_event; 
    555     quadlet_t tmpval; 
    556  
    557     quadlet_t *buffer = (quadlet_t *)(p->getBufferAddress()); 
    558  
    559     assert(nevents + offset <= p->getBufferSize()); 
    560  
    561     buffer+=offset; 
    562  
    563     for ( j = location; j < nevents; j += 8 ) 
    564     { 
    565         target_event = (quadlet_t *) (data + ((j * m_dimension) + position)); 
    566  
    567         if ( *buffer & 0xFF000000 )   // we can send a byte 
    568         { 
    569             tmpval = ((*buffer)<<16) & 0x00FF0000; 
    570             tmpval=IEC61883_AM824_SET_LABEL(tmpval, IEC61883_AM824_LABEL_MIDI_1X); 
    571             *target_event = htonl(tmpval); 
    572  
    573             // debugOutput ( DEBUG_LEVEL_VERBOSE, "MIDI port %s, pos=%u, loc=%u, nevents=%u, dim=%d\n", 
    574             //            p->getName().c_str(), position, location, nevents, m_dimension ); 
    575             // debugOutput ( DEBUG_LEVEL_VERBOSE, "base=%p, target=%p, value=%08X\n", 
    576             //            data, target_event, tmpval ); 
    577         } else { 
    578             // can't send a byte, either because there is no byte, 
    579             // or because this would exceed the maximum rate 
    580             // FIXME: this can be ifdef optimized since it's a constant 
    581             *target_event = htonl(IEC61883_AM824_SET_LABEL(0, IEC61883_AM824_LABEL_MIDI_NO_DATA)); 
    582         } 
    583         buffer+=8; 
    584     } 
    585  
    586     return 0; 
    587 
    588  
    589 int AmdtpTransmitStreamProcessor::encodeSilencePortToMBLAEvents ( AmdtpAudioPort *p, quadlet_t *data, 
    590         unsigned int offset, unsigned int nevents ) 
    591 
    592     unsigned int j=0; 
    593  
    594     quadlet_t *target_event; 
    595  
    596     target_event= ( quadlet_t * ) ( data + p->getPosition() ); 
    597  
    598     switch ( m_StreamProcessorManager.getAudioDataType() ) 
    599     { 
    600         default: 
    601         case StreamProcessorManager::eADT_Int24: 
    602         case StreamProcessorManager::eADT_Float: 
    603         { 
    604             for ( j = 0; j < nevents; j += 1 )   // decode max nsamples 
    605             { 
    606                 *target_event = htonl ( 0x40000000 ); 
    607                 target_event += m_dimension; 
    608             } 
    609         } 
    610         break; 
    611     } 
    612  
    613     return 0; 
    614 
    615  
    616 int AmdtpTransmitStreamProcessor::encodeSilencePortToMidiEvents ( AmdtpMidiPort *p, quadlet_t *data, 
    617         unsigned int offset, unsigned int nevents ) 
    618 
    619     unsigned int j=0; 
    620     unsigned int position = p->getPosition(); 
    621     unsigned int location = p->getLocation(); 
    622  
    623     quadlet_t *target_event; 
    624  
    625     for ( j = location; j < nevents; j += 8 ) 
    626     { 
    627         target_event = (quadlet_t *) (data + ((j * m_dimension) + position)); 
    628         *target_event=htonl(IEC61883_AM824_SET_LABEL(0, IEC61883_AM824_LABEL_MIDI_NO_DATA)); 
    629     } 
    630  
    631     return 0; 
     425    // no need to update the port cache when transmitting silence since 
     426    // no dynamic values are used to do so. 
     427 
     428    encodeAudioPortsSilence((quadlet_t *)data, offset, nevents); 
     429    encodeMidiPortsSilence((quadlet_t *)data, offset, nevents); 
     430    return true; 
    632431} 
    633432 
    634433/** 
    635  * @brief encodes all audio ports in the cache to events 
     434 * @brief encodes all audio ports in the cache to events (silent data) 
    636435 * @param data  
    637436 * @param offset  
    638437 * @param nevents  
    639  * @return  
    640438 */ 
    641 bool 
    642 AmdtpTransmitStreamProcessor::encodeAudioPorts(quadlet_t *data, 
    643                                                unsigned int offset, 
    644                                                unsigned int nevents) 
    645 
    646     unsigned int j=0; 
    647  
     439void 
     440AmdtpTransmitStreamProcessor::encodeAudioPortsSilence(quadlet_t *data, 
     441                                                      unsigned int offset, 
     442                                                      unsigned int nevents) 
     443
     444    unsigned int j; 
    648445    quadlet_t *target_event; 
    649446    unsigned int i; 
     447 
    650448    for (i = 0; i < m_nb_audio_ports; i++) { 
    651         struct _MBLA_port_cache p = m_audio_ports.at(i); 
     449        target_event = (quadlet_t *)(data + i); 
     450 
     451        for (j = 0;j < nevents; j += 1) 
     452        { 
     453            *target_event = htonl( 0x40000000 ); 
     454            target_event += m_dimension; 
     455        } 
     456    } 
     457
     458 
     459/** 
     460 * @brief encodes all audio ports in the cache to events (float data) 
     461 * @param data  
     462 * @param offset  
     463 * @param nevents  
     464 */ 
     465void 
     466AmdtpTransmitStreamProcessor::encodeAudioPortsFloat(quadlet_t *data, 
     467                                                    unsigned int offset, 
     468                                                    unsigned int nevents) 
     469
     470    unsigned int j; 
     471    quadlet_t *target_event; 
     472    unsigned int i; 
     473 
     474    for (i = 0; i < m_nb_audio_ports; i++) { 
     475        struct _MBLA_port_cache &p = m_audio_ports.at(i); 
    652476        target_event = (quadlet_t *)(data + i); 
    653477        assert(nevents + offset <= p.buffer_size ); 
    654478 
    655         switch ( m_StreamProcessorManager.getAudioDataType() ) 
    656         { 
    657             case StreamProcessorManager::eADT_Float: 
     479        float *buffer = (float *)(p.buffer); 
     480        buffer += offset; 
     481 
     482        for (j = 0;j < nevents; j += 1) 
     483        { 
     484            // don't care for overflow 
     485            float v = (*buffer) * AMDTP_FLOAT_MULTIPLIER; 
     486            unsigned int tmp = ((int) v); 
     487            *target_event = htonl ( ( tmp >> 8 ) | 0x40000000 ); 
     488            buffer++; 
     489            target_event += m_dimension; 
     490        } 
     491    } 
     492
     493 
     494/** 
     495 * @brief encodes all audio ports in the cache to events (int24 data) 
     496 * @param data  
     497 * @param offset  
     498 * @param nevents  
     499 */ 
     500void 
     501AmdtpTransmitStreamProcessor::encodeAudioPortsInt24(quadlet_t *data, 
     502                                                    unsigned int offset, 
     503                                                    unsigned int nevents) 
     504
     505    unsigned int j; 
     506    quadlet_t *target_event; 
     507    unsigned int i; 
     508 
     509    for (i = 0; i < m_nb_audio_ports; i++) { 
     510        struct _MBLA_port_cache &p = m_audio_ports.at(i); 
     511        target_event = (quadlet_t *)(data + i); 
     512        assert(nevents + offset <= p.buffer_size ); 
     513 
     514        uint32_t *buffer = (uint32_t *)(p.buffer); 
     515        buffer += offset; 
     516 
     517        for (j = 0; j < nevents; j += 1) 
     518        { 
     519            *target_event = htonl(((*buffer) & 0x00FFFFFF) | 0x40000000); 
     520            buffer++; 
     521            target_event += m_dimension; 
     522        } 
     523    } 
     524
     525 
     526/** 
     527 * @brief encodes all midi ports in the cache to events (silence) 
     528 * @param data  
     529 * @param offset  
     530 * @param nevents  
     531 */ 
     532void 
     533AmdtpTransmitStreamProcessor::encodeMidiPortsSilence(quadlet_t *data, 
     534                                                     unsigned int offset, 
     535                                                     unsigned int nevents) 
     536
     537    quadlet_t *target_event; 
     538    unsigned int i,j; 
     539 
     540    for (i = 0; i < m_nb_midi_ports; i++) { 
     541        struct _MIDI_port_cache &p = m_midi_ports.at(i); 
     542 
     543        for (j = p.location;j < nevents; j += 8) { 
     544            target_event = (quadlet_t *) (data + ((j * m_dimension) + p.position)); 
     545            *target_event = htonl(IEC61883_AM824_SET_LABEL(0, IEC61883_AM824_LABEL_MIDI_NO_DATA)); 
     546        } 
     547    } 
     548
     549 
     550/** 
     551 * @brief encodes all midi ports in the cache to events 
     552 * @param data  
     553 * @param offset  
     554 * @param nevents  
     555 */ 
     556void 
     557AmdtpTransmitStreamProcessor::encodeMidiPorts(quadlet_t *data, 
     558                                              unsigned int offset, 
     559                                              unsigned int nevents) 
     560
     561    quadlet_t *target_event; 
     562    unsigned int i,j; 
     563 
     564    for (i = 0; i < m_nb_midi_ports; i++) { 
     565        struct _MIDI_port_cache &p = m_midi_ports.at(i); 
     566        uint32_t *buffer = (quadlet_t *)(p.buffer); 
     567        buffer += offset; 
     568 
     569        for (j = p.location;j < nevents; j += 8) { 
     570            target_event = (quadlet_t *) (data + ((j * m_dimension) + p.position)); 
     571            if ( *buffer & 0xFF000000 )   // we can send a byte 
    658572            { 
    659                 float *buffer = (float *)(p.buffer); 
    660                 buffer += offset; 
    661  
    662                 for (j = 0;j < nevents; j += 1)   // decode max nsamples 
    663                 { 
    664                     // don't care for overflow 
    665                     float v = (*buffer) * AMDTP_FLOAT_MULTIPLIER; 
    666                     unsigned int tmp = ((int) v); 
    667                     *target_event = htonl ( ( tmp >> 8 ) | 0x40000000 ); 
    668                     buffer++; 
    669                     target_event += m_dimension; 
    670                 } 
     573                quadlet_t tmpval; 
     574                tmpval = ((*buffer)<<16) & 0x00FF0000; 
     575                tmpval = IEC61883_AM824_SET_LABEL(tmpval, IEC61883_AM824_LABEL_MIDI_1X); 
     576                *target_event = htonl(tmpval); 
     577     
     578                // debugOutput ( DEBUG_LEVEL_VERBOSE, "MIDI port %s, pos=%u, loc=%u, nevents=%u, dim=%d\n", 
     579                //            p->getName().c_str(), position, location, nevents, m_dimension ); 
     580                // debugOutput ( DEBUG_LEVEL_VERBOSE, "base=%p, target=%p, value=%08X\n", 
     581                //            data, target_event, tmpval ); 
     582            } else { 
     583                // can't send a byte, either because there is no byte, 
     584                // or because this would exceed the maximum rate 
     585                // FIXME: this can be ifdef optimized since it's a constant 
     586                *target_event = htonl(IEC61883_AM824_SET_LABEL(0, IEC61883_AM824_LABEL_MIDI_NO_DATA)); 
    671587            } 
    672             break; 
    673             case StreamProcessorManager::eADT_Int24: 
    674             { 
    675                 uint32_t *buffer = (uint32_t *)(p.buffer); 
    676                 buffer += offset; 
    677  
    678                 for (j = 0; j < nevents; j += 1)   // decode max nsamples 
    679                 { 
    680                     *target_event = htonl(((*buffer) & 0x00FFFFFF) | 0x40000000); 
    681                     buffer++; 
    682                     target_event += m_dimension; 
    683                 } 
    684             } 
    685             break; 
    686             default: 
    687                 debugError("bad type: %d\n", m_StreamProcessorManager.getAudioDataType()); 
    688                 return false; 
    689         } 
    690     } 
    691     return true; 
    692 
    693  
     588            buffer+=8; 
     589        } 
     590    } 
     591
    694592 
    695593bool 
     
    699597    // and have very efficient lookups: 
    700598    // m_float_ports.at(i).buffer -> audio stream i buffer 
     599    // for midi ports we simply cache all port info since they are (usually) not 
     600    // that numerous 
    701601    m_nb_audio_ports = 0; 
    702602    m_audio_ports.clear(); 
    703603     
    704604    m_nb_midi_ports = 0; 
     605    m_midi_ports.clear(); 
    705606     
    706607    for(PortVectorIterator it = m_Ports.begin(); 
     
    742643                    return false; 
    743644                } 
    744 //                p.position = pinfo->getPosition(); 
    745645                p.buffer = NULL; // to be filled by updatePortCache 
    746 #ifdef DEBUG 
     646                #ifdef DEBUG 
    747647                p.buffer_size = (*it)->getBufferSize(); 
    748 #endif 
     648                #endif 
    749649 
    750650                m_audio_ports.push_back(p); 
     
    760660    } 
    761661 
     662    for(PortVectorIterator it = m_Ports.begin(); 
     663        it != m_Ports.end(); 
     664        ++it ) 
     665    { 
     666        AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it); 
     667        debugOutput(DEBUG_LEVEL_VERBOSE, "idx %u: looking at port %s at position %u, location %u\n", 
     668                                        idx, (*it)->getName().c_str(), pinfo->getPosition(), pinfo->getLocation()); 
     669        if ((*it)->getPortType() == Port::E_Midi) { 
     670            struct _MIDI_port_cache p; 
     671            p.port = dynamic_cast<AmdtpMidiPort *>(*it); 
     672            if(p.port == NULL) { 
     673                debugError("Port is not an AmdtpMidiPort!\n"); 
     674                return false; 
     675            } 
     676            p.position = pinfo->getPosition(); 
     677            p.location = pinfo->getLocation(); 
     678            p.buffer = NULL; // to be filled by updatePortCache 
     679            #ifdef DEBUG 
     680            p.buffer_size = (*it)->getBufferSize(); 
     681            #endif 
     682 
     683            m_midi_ports.push_back(p); 
     684            debugOutput(DEBUG_LEVEL_VERBOSE, "Cached port %s at position %u, location %u\n", 
     685                                            p.port->getName().c_str(), p.position, p.location); 
     686        } 
     687    } 
     688 
    762689    return true; 
    763690} 
     
    767694    unsigned int idx; 
    768695    for (idx = 0; idx < m_nb_audio_ports; idx++) { 
    769         AmdtpAudioPort *port = m_audio_ports.at(idx).port; 
    770         m_audio_ports.at(idx).buffer = port->getBufferAddress(); 
     696        struct _MBLA_port_cache& p = m_audio_ports.at(idx); 
     697        AmdtpAudioPort *port = p.port; 
     698        p.buffer = port->getBufferAddress(); 
     699    } 
     700    for (idx = 0; idx < m_nb_midi_ports; idx++) { 
     701        struct _MIDI_port_cache& p = m_midi_ports.at(idx); 
     702        AmdtpMidiPort *port = p.port; 
     703        p.buffer = port->getBufferAddress(); 
    771704    } 
    772705} 
  • branches/api-cleanup/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h

    r816 r817  
    115115                        unsigned int offset); 
    116116 
    117     int encodePortToMBLAEvents(AmdtpAudioPort *, quadlet_t *data, 
    118                                unsigned int offset, unsigned int nevents); 
    119     int encodePortToMidiEvents(AmdtpMidiPort *p, quadlet_t *data, 
    120                                unsigned int offset, unsigned int nevents); 
    121     int encodeSilencePortToMBLAEvents(AmdtpAudioPort *, quadlet_t *data, 
    122                                       unsigned int offset, unsigned int nevents); 
    123     int encodeSilencePortToMidiEvents(AmdtpMidiPort *p, quadlet_t *data, 
    124                                       unsigned int offset, unsigned int nevents); 
    125  
    126     bool encodeAudioPorts(quadlet_t *data, unsigned int offset, unsigned int nevents); 
     117    void encodeAudioPortsSilence(quadlet_t *data, unsigned int offset, unsigned int nevents); 
     118    void encodeAudioPortsFloat(quadlet_t *data, unsigned int offset, unsigned int nevents); 
     119    void encodeAudioPortsInt24(quadlet_t *data, unsigned int offset, unsigned int nevents); 
     120    void encodeMidiPortsSilence(quadlet_t *data, unsigned int offset, unsigned int nevents); 
     121    void encodeMidiPorts(quadlet_t *data, unsigned int offset, unsigned int nevents); 
    127122 
    128123    unsigned int getFDF(); 
     
    145140    std::vector<struct _MBLA_port_cache> m_audio_ports; 
    146141    unsigned int m_nb_audio_ports; 
     142 
     143    struct _MIDI_port_cache { 
     144        AmdtpMidiPort*      port; 
     145        void*               buffer; 
     146        unsigned int        position; 
     147        unsigned int        location; 
     148#ifdef DEBUG 
     149        unsigned int        buffer_size; 
     150#endif 
     151    }; 
     152    std::vector<struct _MIDI_port_cache> m_midi_ports; 
    147153    unsigned int m_nb_midi_ports; 
    148154 
    149155    bool initPortCache(); 
    150156    void updatePortCache(); 
    151  
    152157}; 
    153158