Changeset 809

Show
Ignore:
Timestamp:
01/05/08 09:40:06 (13 years ago)
Author:
ppalmers
Message:

First round of cleanup:
- make Ports auto-register to a PortManager?
- remove the different 'signal' types, everything is now period-signaled.
- removed obsolete streaming test programs

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/api-cleanup/libffado/ffado.h

    r742 r809  
    206206 
    207207/** 
    208  *  
     208 * 
    209209 * Buffer types known to the API 
    210  *  
     210 * 
    211211 */ 
    212212typedef enum { 
    213     ffado_buffer_type_per_stream      = -1, // use this to use the per-stream read functions 
    214213    ffado_buffer_type_int24           =  0, 
    215214    ffado_buffer_type_float           =  1, 
     
    412411 
    413412/** 
    414  * Reads from a specific channel to a supplied buffer. 
    415  *  
    416  * @param dev the ffado device 
    417  * @param number the stream number 
    418  * @param buffer the buffer to copy the samples into 
    419  * @param nsamples the number of samples to be read. the buffer has to be big enough for this amount of samples. 
    420  * 
    421  * @return the amount of samples actually read. -1 on error (xrun). 
    422  */ 
    423 int ffado_streaming_read(ffado_device_t *dev, int number, ffado_sample_t *buffer, int nsamples); 
    424  
    425 /** 
    426  * Write to a specific channel from a supplied buffer. 
    427  *  
    428  * @param dev the ffado device 
    429  * @param number the stream number 
    430  * @param buffer the buffer to copy the samples from 
    431  * @param nsamples the number of samples to be written. 
    432  * 
    433  * @return the amount of samples actually written. -1 on error. 
    434  */ 
    435 int ffado_streaming_write(ffado_device_t *dev, int number, ffado_sample_t *buffer, int nsamples); 
    436  
    437 /** 
    438413 * Transfer & decode the events from the packet buffer to the sample buffers 
    439414 *  
  • branches/api-cleanup/SConstruct

    r806 r809  
    331331        env['REVISION'] = '' 
    332332 
    333 env['FFADO_API_VERSION']="5
     333env['FFADO_API_VERSION']="6
    334334 
    335335env['PACKAGE'] = "libffado" 
    336 env['VERSION'] = "1.999.11
     336env['VERSION'] = "1.999.12
    337337env['LIBVERSION'] = "1.0.0" 
    338338 
  • branches/api-cleanup/src/bounce/bounce_avdevice.cpp

    r742 r809  
    212212        Streaming::Port *p=NULL; 
    213213        p=new Streaming::AmdtpAudioPort( 
     214                *processor, 
    214215                buff, 
    215216                direction, 
     
    224225        if (!p) { 
    225226            debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",buff); 
    226         } else { 
    227  
    228             if (!processor->addPort(p)) { 
    229                 debugWarning("Could not register port with stream processor\n"); 
    230                 free(buff); 
    231                 return false; 
    232             } else { 
    233                 debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",buff); 
    234             } 
    235227        } 
    236228        free(buff); 
     
    243235        Streaming::Port *p=NULL; 
    244236        p=new Streaming::AmdtpMidiPort( 
     237                *processor, 
    245238                buff, 
    246239                direction, 
     
    255248        if (!p) { 
    256249            debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",buff); 
    257         } else { 
    258  
    259             if (!processor->addPort(p)) { 
    260                 debugWarning("Could not register port with stream processor\n"); 
    261                 free(buff); 
    262                 return false; 
    263             } else { 
    264                 debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",buff); 
    265             } 
    266250        } 
    267251        free(buff); 
  • branches/api-cleanup/src/dice/dice_avdevice.cpp

    r785 r809  
    839839    case ePT_Analog: 
    840840        p=new Streaming::AmdtpAudioPort( 
     841                *processor, 
    841842                portname.str(), 
    842843                direction, 
     
    849850    case ePT_MIDI: 
    850851        p=new Streaming::AmdtpMidiPort( 
     852                *processor, 
    851853                portname.str(), 
    852854                direction, 
     
    864866    if (!p) { 
    865867        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->name.c_str()); 
    866     } else { 
    867  
    868         if (!processor->addPort(p)) { 
    869             debugWarning("Could not register port with stream processor\n"); 
    870             return false; 
    871         } 
    872868    } 
    873869 
  • branches/api-cleanup/src/ffado.cpp

    r807 r809  
    263263} 
    264264 
    265  
    266 int ffado_streaming_write(ffado_device_t *dev, int i, ffado_sample_t *buffer, int nsamples) { 
    267     Streaming::Port *p = dev->m_deviceManager->getStreamProcessorManager().getPortByIndex(i, Streaming::Port::E_Playback); 
    268     // use an assert here performancewise, 
    269     // it should already have failed before, if not correct 
    270     assert(p); 
    271  
    272     return p->writeEvents((void *)buffer, nsamples); 
    273 } 
    274  
    275 int ffado_streaming_read(ffado_device_t *dev, int i, ffado_sample_t *buffer, int nsamples) { 
    276     Streaming::Port *p=dev->m_deviceManager->getStreamProcessorManager().getPortByIndex(i, Streaming::Port::E_Capture); 
    277     // use an assert here performancewise, 
    278     // it should already have failed before, if not correct 
    279     assert(p); 
    280  
    281     return p->readEvents((void *)buffer, nsamples); 
    282 } 
    283  
    284265int ffado_streaming_get_nb_capture_streams(ffado_device_t *dev) { 
    285266    return dev->m_deviceManager->getStreamProcessorManager().getPortCount(Streaming::Port::E_Capture); 
     
    370351            return -1; 
    371352        } 
    372         if (!p->setBufferType(Streaming::Port::E_PointerBuffer)) { 
    373             debugWarning("%s: Could not set buffer type to Pointerbuffer\n",p->getName().c_str()); 
    374             return -1; 
    375         } 
    376353        break; 
    377354    case ffado_buffer_type_float: 
    378355        if (!p->setDataType(Streaming::Port::E_Float)) { 
    379356            debugWarning("%s: Could not set data type to Float\n",p->getName().c_str()); 
    380             return -1; 
    381         } 
    382         if (!p->setBufferType(Streaming::Port::E_PointerBuffer)) { 
    383             debugWarning("%s: Could not set buffer type to Pointerbuffer\n",p->getName().c_str()); 
    384357            return -1; 
    385358        } 
     
    390363            return -1; 
    391364        } 
    392         if (!p->setBufferType(Streaming::Port::E_RingBuffer)) { 
    393             debugWarning("%s: Could not set buffer type to Ringbuffer\n",p->getName().c_str()); 
    394             return -1; 
    395         } 
    396365        break; 
    397366    default: 
    398         debugWarning("%s: Unsupported buffer type\n",p->getName().c_str()); 
     367        debugWarning("%s: Unsupported buffer type (%d)\n", p->getName().c_str(), t); 
    399368        return -1; 
    400369    } 
     
    435404} 
    436405 
    437 // TODO: the way port buffers are set in the C api doesn't satisfy me 
    438406int ffado_streaming_set_capture_stream_buffer(ffado_device_t *dev, int i, char *buff) { 
    439407        Streaming::Port *p = dev->m_deviceManager->getStreamProcessorManager().getPortByIndex(i, Streaming::Port::E_Capture); 
    440  
    441408        // use an assert here performancewise, 
    442409        // it should already have failed before, if not correct 
    443410        assert(p); 
    444  
    445         p->useExternalBuffer(true); 
    446         p->setExternalBufferAddress((void *)buff); 
    447  
    448         return 0; 
    449  
     411        p->setBufferAddress((void *)buff); 
     412        return 0; 
    450413} 
    451414 
     
    455418        // it should already have failed before, if not correct 
    456419        assert(p); 
    457  
    458         p->useExternalBuffer(true); 
    459         p->setExternalBufferAddress((void *)buff); 
    460  
    461         return 0; 
    462 
     420        p->setBufferAddress((void *)buff); 
     421        return 0; 
     422
  • branches/api-cleanup/src/genericavc/avc_avdevice.cpp

    r784 r809  
    443443    } 
    444444 
    445     if (!addPlugToProcessor(*outputPlug,p, 
     445    if (!addPlugToProcessor(*outputPlug, p, 
    446446        Streaming::Port::E_Capture)) { 
    447447        debugFatal("Could not add plug to processor!\n"); 
     
    472472 
    473473    if (snoopMode) { 
    474         if (!addPlugToProcessor(*inputPlug,p, 
     474        if (!addPlugToProcessor(*inputPlug, p, 
    475475            Streaming::Port::E_Capture)) { 
    476476            debugFatal("Could not add plug to processor!\n"); 
     
    478478        } 
    479479    } else { 
    480         if (!addPlugToProcessor(*inputPlug,p, 
     480        if (!addPlugToProcessor(*inputPlug, p, 
    481481            Streaming::Port::E_Playback)) { 
    482482            debugFatal("Could not add plug to processor!\n"); 
     
    532532                    channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location); 
    533533                p=new Streaming::AmdtpAudioPort( 
     534                        *processor, 
    534535                        portname.str(), 
    535536                        direction, 
     
    544545                    channelInfo->m_name.c_str(), channelInfo->m_streamPosition, processor->getPortCount(Streaming::Port::E_Midi)); 
    545546                p=new Streaming::AmdtpMidiPort( 
     547                        *processor, 
    546548                        portname.str(), 
    547549                        direction, 
     
    565567                    channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location); 
    566568                p=new Streaming::AmdtpAudioPort( 
     569                        *processor, 
    567570                        portname.str(), 
    568571                        direction, 
     
    581584            if (!p) { 
    582585                debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str()); 
    583             } else { 
    584  
    585                 if (!processor->addPort(p)) { 
    586                     debugWarning("Could not register port with stream processor\n"); 
    587                     return false; 
    588                 } 
    589586            } 
    590587         } 
  • branches/api-cleanup/src/libstreaming/amdtp/AmdtpPort.h

    r742 r809  
    4747public: 
    4848 
    49     AmdtpAudioPort(std::string name, 
    50                        enum E_Direction direction, 
     49    AmdtpAudioPort(PortManager &m, 
     50                   std::string name, 
     51                   enum E_Direction direction, 
    5152                   int position, 
    5253                   int location, 
    5354                   enum E_Formats format) 
    54     : AudioPort(name, direction), 
     55    : AudioPort(m, name, direction), 
    5556      AmdtpPortInfo(position, location, format) 
    5657    {}; 
    5758 
    5859    virtual ~AmdtpAudioPort() {}; 
    59  
    60 protected: 
    61  
    6260}; 
    6361 
     
    7472public: 
    7573 
    76     AmdtpMidiPort(std::string name, 
    77                        enum E_Direction direction, 
    78                    int position, 
    79                    int location, 
    80                    enum E_Formats format) 
    81         : MidiPort(name, direction), 
     74    AmdtpMidiPort(PortManager &m, 
     75                  std::string name, 
     76                  enum E_Direction direction, 
     77                  int position, 
     78                  int location, 
     79                  enum E_Formats format) 
     80        : MidiPort(m, name, direction), 
    8281          AmdtpPortInfo(position, location, format) 
    8382    {}; 
    8483 
    85  
    8684    virtual ~AmdtpMidiPort() {}; 
    87  
    88 protected: 
    89  
    9085}; 
    9186 
  • branches/api-cleanup/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp

    r790 r809  
    167167 
    168168    if(m_data_buffer->writeFrames(nevents, (char *)(data+8), m_last_timestamp)) { 
    169         // process all ports that should be handled on a per-packet base 
    170         // this is MIDI for AMDTP (due to the need of DBC) 
    171         if(isRunning()) { 
    172             if (!decodePacketPorts((quadlet_t *)(data+8), nevents, packet->dbc)) { 
    173                 debugWarning("Problem decoding Packet Ports\n"); 
    174             } 
    175         } 
    176169        return eCRV_OK; 
    177170    } else { 
     
    193186    bool no_problem=true; 
    194187 
    195     for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    196           it != m_PeriodPorts.end(); 
     188    for ( PortVectorIterator it = m_Ports.begin(); 
     189          it != m_Ports.end(); 
    197190          ++it ) 
    198191    { 
     
    213206        case AmdtpPortInfo::E_SPDIF: // still unimplemented 
    214207            break; 
    215     /* for this processor, midi is a packet based port 
    216208        case AmdtpPortInfo::E_Midi: 
    217             break;*/ 
     209            if(decodeMidiEventsToPort(static_cast<AmdtpMidiPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
     210                debugWarning("Could not decode packet Midi to port %s",(*it)->getName().c_str()); 
     211                no_problem=false; 
     212            } 
     213            break; 
    218214        default: // ignore 
    219215            break; 
     
    223219} 
    224220 
    225 /** 
    226  * @brief decode a packet for the packet-based ports 
    227  * 
    228  * @param data Packet data 
    229  * @param nevents number of events in data (including events of other ports & port types) 
    230  * @param dbc DataBlockCount value for this packet 
    231  * @return true if all successfull 
    232  */ 
    233 bool AmdtpReceiveStreamProcessor::decodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc) 
    234 { 
    235     bool ok=true; 
    236  
    237     quadlet_t *target_event=NULL; 
    238     unsigned int j; 
    239  
    240     for ( PortVectorIterator it = m_PacketPorts.begin(); 
    241           it != m_PacketPorts.end(); 
    242           ++it ) 
    243     { 
    244  
    245 #ifdef DEBUG 
    246         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it); 
    247         assert(pinfo); // this should not fail!! 
    248  
    249         // the only packet type of events for AMDTP is MIDI in mbla 
    250         assert(pinfo->getFormat()==AmdtpPortInfo::E_Midi); 
    251 #endif 
    252         AmdtpMidiPort *mp=static_cast<AmdtpMidiPort *>(*it); 
    253  
    254         // we decode this directly (no function call) due to the high frequency 
    255         /* idea: 
    256         spec says: current_midi_port=(dbc+j)%8; 
    257         => if we start at (dbc+stream->location-1)%8, 
    258         we'll start at the right event for the midi port. 
    259         => if we increment j with 8, we stay at the right event. 
    260         */ 
    261         // FIXME: as we know in advance how big a packet is (syt_interval) we can 
    262         //        predict how much loops will be present here 
    263         for(j = (dbc & 0x07)+mp->getLocation(); j < nevents; j += 8) { 
    264             target_event=(quadlet_t *)(data + ((j * m_dimension) + mp->getPosition())); 
    265             quadlet_t sample_int=ntohl(*target_event); 
    266             // FIXME: this assumes that 2X and 3X speed isn't used, 
    267             // because only the 1X slot is put into the ringbuffer 
    268             if(IEC61883_AM824_GET_LABEL(sample_int) != IEC61883_AM824_LABEL_MIDI_NO_DATA) { 
    269                 sample_int=(sample_int >> 16) & 0x000000FF; 
    270                 if(!mp->writeEvent(&sample_int)) { 
    271                     debugWarning("Packet port events lost\n"); 
    272                     ok=false; 
    273                 } 
    274             } 
    275         } 
    276  
    277     } 
    278  
    279     return ok; 
    280 } 
    281  
    282221#if USE_SSE 
     222#error broken 
    283223typedef float v4sf __attribute__ ((vector_size (16))); 
    284224typedef int v4si __attribute__ ((vector_size (16))); 
     
    306246    switch(p->getDataType()) { 
    307247        default: 
     248            debugError("bad type: %d\n", p->getDataType()); 
     249            return -1; 
    308250        case Port::E_Int24: 
    309251            { 
     
    374316} 
    375317 
     318int 
     319AmdtpReceiveStreamProcessor::decodeMidiEventsToPort( 
     320                       AmdtpMidiPort *p, quadlet_t *data, 
     321                       unsigned int offset, unsigned int nevents) 
     322{ 
     323    #warning implement 
     324} 
     325 
    376326#else 
    377327 
     
    388338    switch(p->getDataType()) { 
    389339        default: 
     340            debugError("bad type: %d\n", p->getDataType()); 
     341            return -1; 
    390342        case Port::E_Int24: 
    391343            { 
     
    429381    return 0; 
    430382} 
     383 
     384int 
     385AmdtpReceiveStreamProcessor::decodeMidiEventsToPort( 
     386                       AmdtpMidiPort *p, quadlet_t *data, 
     387                       unsigned int offset, unsigned int nevents) 
     388{ 
     389    unsigned int j=0; 
     390    quadlet_t *target_event; 
     391    quadlet_t sample_int; 
     392    unsigned int position = p->getPosition(); 
     393    unsigned int location = p->getLocation(); 
     394 
     395    switch(p->getDataType()) { 
     396        default: 
     397            debugError("bad type: %d\n", p->getDataType()); 
     398            return -1; 
     399        case Port::E_MidiEvent: 
     400            { 
     401                quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress()); 
     402 
     403                assert(nevents + offset <= p->getBufferSize()); 
     404 
     405                buffer+=offset; 
     406 
     407                // clear 
     408                memset(buffer, 0, nevents * 4); 
     409 
     410                // assumes that dbc%8 == 0, which is always true if data points to the 
     411                // start of a packet in blocking mode 
     412                // midi events that belong to the same time mpx-ed block should all be 
     413                // timed at the SYT timestamp of the packet. This basically means that they 
     414                // all correspond to the first audio frame in the packet. 
     415                for(j = location; j < nevents; j += 8) { 
     416                    target_event=(quadlet_t *)(data + ((j * m_dimension) + position)); 
     417                    sample_int=ntohl(*target_event); 
     418                    // FIXME: this assumes that 2X and 3X speed isn't used, 
     419                    // because only the 1X slot is put into the ringbuffer 
     420                    if(IEC61883_AM824_GET_LABEL(sample_int) != IEC61883_AM824_LABEL_MIDI_NO_DATA) { 
     421                        sample_int=(sample_int >> 16) & 0x000000FF; 
     422                        sample_int |= 0x01000000; // flag that there is a midi event present 
     423                    } 
     424                    *buffer = sample_int; 
     425                    buffer += 8; // skip 8 frames 
     426                } 
     427            } 
     428            break; 
     429    } 
     430 
     431    return 0; 
     432} 
     433 
    431434#endif 
    432435} // end of namespace Streaming 
  • branches/api-cleanup/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.h

    r750 r809  
    101101 
    102102private: 
    103     bool decodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc); 
    104103    int decodeMBLAEventsToPort(AmdtpAudioPort *, quadlet_t *data, unsigned int offset, unsigned int nevents); 
     104    int decodeMidiEventsToPort(AmdtpMidiPort *p, quadlet_t *data, unsigned int offset, unsigned int nevents); 
    105105 
    106106    unsigned int getSytInterval(); 
  • branches/api-cleanup/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp

    r798 r809  
    249249    int cycle, unsigned int dropped, unsigned int max_length ) 
    250250{ 
    251     struct iec61883_packet *packet = ( struct iec61883_packet * ) data; 
    252251    if ( m_data_buffer->readFrames ( m_syt_interval, ( char * ) ( data + 8 ) ) ) 
    253252    { 
    254         // process all ports that should be handled on a per-packet base 
    255         // this is MIDI for AMDTP (due to the need of DBC) 
    256         if ( !encodePacketPorts ( ( quadlet_t * ) ( data+8 ), m_syt_interval, packet->dbc ) ) 
    257         { 
    258             debugWarning ( "Problem encoding Packet Ports\n" ); 
    259         } 
    260253        debugOutput ( DEBUG_LEVEL_ULTRA_VERBOSE, "XMIT DATA (cy %04d): TSP=%011llu (%04u)\n", 
    261254                    cycle, m_last_timestamp, ( unsigned int ) TICKS_TO_CYCLES ( m_last_timestamp ) ); 
     
    395388        m_syt_interval ); 
    396389 
    397     for ( PortVectorIterator it = m_Ports.begin(); 
    398             it != m_Ports.end(); 
    399             ++it ) 
    400     { 
    401         if ( ( *it )->getPortType() == Port::E_Midi ) 
    402         { 
    403             // we use a timing unit of 10ns 
    404             // this makes sure that for the max syt interval 
    405             // we don't have rounding, and keeps the numbers low 
    406             // we have 1 slot every 8 events 
    407             // we have syt_interval events per packet 
    408             // => syt_interval/8 slots per packet 
    409             // packet rate is 8000pkt/sec => interval=125us 
    410             // so the slot interval is (1/8000)/(syt_interval/8) 
    411             // or: 1/(1000 * syt_interval) sec 
    412             // which is 1e9/(1000*syt_interval) nsec 
    413             // or 100000/syt_interval 'units' 
    414             // the event interval is fixed to 320us = 32000 'units' 
    415             if ( ! ( *it )->useRateControl ( true, ( 100000/m_syt_interval ),32000, false ) ) 
    416             { 
    417                 debugFatal ( "Could not set signal type to PeriodSignalling" ); 
    418                 return false; 
    419             } 
    420             break; 
    421         } 
    422     } 
    423390    return true; 
    424391} 
     
    432399    bool no_problem = true; 
    433400 
    434     for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    435           it != m_PeriodPorts.end(); 
     401    for ( PortVectorIterator it = m_Ports.begin(); 
     402          it != m_Ports.end(); 
    436403          ++it ) 
    437404    { 
     
    453420            case AmdtpPortInfo::E_SPDIF: // still unimplemented 
    454421                break; 
     422            case AmdtpPortInfo::E_Midi: 
     423                if( encodePortToMidiEvents(static_cast<AmdtpMidiPort *>(*it), (quadlet_t *)data, offset, nevents) ) 
     424                { 
     425                    debugWarning ( "Could not encode port %s to Midi events", (*it)->getName().c_str() ); 
     426                    no_problem = false; 
     427                } 
     428                break; 
    455429            default: // ignore 
    456430                break; 
     
    465439{ 
    466440    bool no_problem = true; 
    467     for(PortVectorIterator it = m_PeriodPorts.begin(); 
    468         it != m_PeriodPorts.end(); 
     441    for(PortVectorIterator it = m_Ports.begin(); 
     442        it != m_Ports.end(); 
    469443        ++it ) 
    470444    { 
     
    478452                if ( encodeSilencePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents) ) 
    479453                { 
    480                     debugWarning("Could not encode port %s to MBLA events", (*it)->getName().c_str()); 
     454                    debugWarning("Could not encode silence for port %s to MBLA events", (*it)->getName().c_str()); 
    481455                    no_problem = false; 
    482456                } 
     
    484458            case AmdtpPortInfo::E_SPDIF: // still unimplemented 
    485459                break; 
     460            case AmdtpPortInfo::E_Midi: 
     461                if( encodeSilencePortToMidiEvents(static_cast<AmdtpMidiPort *>(*it), (quadlet_t *)data, offset, nevents) ) 
     462                { 
     463                    debugWarning ( "Could not encode silence for port %s to Midi events", (*it)->getName().c_str() ); 
     464                    no_problem = false; 
     465                } 
     466                break; 
    486467            default: // ignore 
    487468                break; 
     
    491472} 
    492473 
    493 /** 
    494 * @brief decode a packet for the packet-based ports 
    495 * 
    496 * @param data Packet data 
    497 * @param nevents number of events in data (including events of other ports & port types) 
    498 * @param dbc DataBlockCount value for this packet 
    499 * @return true if all successfull 
    500 */ 
    501 bool AmdtpTransmitStreamProcessor::encodePacketPorts ( quadlet_t *data, unsigned int nevents, unsigned int dbc ) 
    502 { 
    503     bool ok=true; 
    504     quadlet_t byte; 
    505  
    506     quadlet_t *target_event=NULL; 
    507     unsigned int j; 
    508  
    509     for ( PortVectorIterator it = m_PacketPorts.begin(); 
    510             it != m_PacketPorts.end(); 
    511             ++it ) 
    512     { 
    513  
    514 #ifdef DEBUG 
    515         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *> ( *it ); 
    516         assert ( pinfo ); // this should not fail!! 
    517  
    518         // the only packet type of events for AMDTP is MIDI in mbla 
    519         assert ( pinfo->getFormat() ==AmdtpPortInfo::E_Midi ); 
    520 #endif 
    521  
    522         AmdtpMidiPort *mp=static_cast<AmdtpMidiPort *> ( *it ); 
    523  
    524         // we encode this directly (no function call) due to the high frequency 
    525         /* idea: 
    526         spec says: current_midi_port=(dbc+j)%8; 
    527         => if we start at (dbc+stream->location-1)%8, 
    528         we'll start at the right event for the midi port. 
    529         => if we increment j with 8, we stay at the right event. 
    530         */ 
    531         // FIXME: as we know in advance how big a packet is (syt_interval) we can 
    532         //        predict how much loops will be present here 
    533         // first prefill the buffer with NO_DATA's on all time muxed channels 
    534  
    535         for ( j = ( dbc & 0x07 ) +mp->getLocation(); j < nevents; j += 8 ) 
    536         { 
    537  
    538             quadlet_t tmpval; 
    539  
    540             target_event= ( quadlet_t * ) ( data + ( ( j * m_dimension ) + mp->getPosition() ) ); 
    541  
    542             if ( mp->canRead() )   // we can send a byte 
    543             { 
    544                 mp->readEvent ( &byte ); 
    545                 byte &= 0xFF; 
    546                 tmpval=htonl ( 
    547                         IEC61883_AM824_SET_LABEL ( ( byte ) <<16, 
    548                                                     IEC61883_AM824_LABEL_MIDI_1X ) ); 
    549  
    550                 debugOutput ( DEBUG_LEVEL_ULTRA_VERBOSE, "MIDI port %s, pos=%d, loc=%d, dbc=%d, nevents=%d, dim=%d\n", 
    551                             mp->getName().c_str(), mp->getPosition(), mp->getLocation(), dbc, nevents, m_dimension ); 
    552                 debugOutput ( DEBUG_LEVEL_ULTRA_VERBOSE, "base=%p, target=%p, value=%08X\n", 
    553                             data, target_event, tmpval ); 
    554  
    555             } 
    556             else 
    557             { 
    558                 // can't send a byte, either because there is no byte, 
    559                 // or because this would exceed the maximum rate 
    560                 tmpval=htonl ( 
    561                         IEC61883_AM824_SET_LABEL ( 0,IEC61883_AM824_LABEL_MIDI_NO_DATA ) ); 
    562             } 
    563  
    564             *target_event=tmpval; 
    565         } 
    566  
    567     } 
    568     return ok; 
    569 } 
    570  
    571474#if USE_SSE 
     475#error Broken 
    572476typedef float v4sf __attribute__ ((vector_size (16))); 
    573477typedef int v4si __attribute__ ((vector_size (16))); 
     
    600504    { 
    601505        default: 
     506            debugError("bad type: %d\n", p->getDataType()); 
     507            return -1; 
    602508        case Port::E_Int24: 
    603509        { 
     
    687593    { 
    688594        default: 
     595            debugError("bad type: %d\n", p->getDataType()); 
     596            return -1; 
    689597        case Port::E_Int24: 
    690598        { 
     
    729637    return 0; 
    730638} 
     639 
     640// note: make sure that the midi events in the port buffer are only placed on (buffer+offset+x)%8 == 0 
     641// i.e. 8 frame aligned 
     642int AmdtpTransmitStreamProcessor::encodePortToMidiEvents ( AmdtpMidiPort *p, quadlet_t *data, 
     643        unsigned int offset, unsigned int nevents ) 
     644{ 
     645    unsigned int j=0; 
     646    unsigned int position = p->getPosition(); 
     647    unsigned int location = p->getLocation(); 
     648    char byte; 
     649     
     650    quadlet_t *target_event; 
     651    quadlet_t tmpval; 
     652 
     653    switch ( p->getDataType() ) 
     654    { 
     655        default: 
     656            debugError("bad type: %d\n", p->getDataType()); 
     657            return -1; 
     658        case Port::E_Midi: 
     659        { 
     660            quadlet_t *buffer = (quadlet_t *)(p->getBufferAddress()); 
     661 
     662            assert(nevents + offset <= p->getBufferSize()); 
     663 
     664            buffer+=offset; 
     665 
     666            for ( j = location; j < nevents; j += 8 ) 
     667            { 
     668                target_event = (quadlet_t *) (data + ((j * m_dimension) + position)); 
     669 
     670                if ( *buffer & 0xFF000000 )   // we can send a byte 
     671                { 
     672                    byte = *buffer & 0xFF; 
     673                    tmpval=htonl(IEC61883_AM824_SET_LABEL((byte)<<16, IEC61883_AM824_LABEL_MIDI_1X)); 
     674     
     675//                     debugOutput ( DEBUG_LEVEL_ULTRA_VERBOSE, "MIDI port %s, pos=%d, loc=%d, nevents=%d, dim=%d\n", 
     676//                                 p->getName().c_str(), position, location, nevents, m_dimension ); 
     677//                     debugOutput ( DEBUG_LEVEL_ULTRA_VERBOSE, "base=%p, target=%p, value=%08X\n", 
     678//                                 data, target_event, tmpval ); 
     679                } else { 
     680                    // can't send a byte, either because there is no byte, 
     681                    // or because this would exceed the maximum rate 
     682                    tmpval=htonl(IEC61883_AM824_SET_LABEL(0, IEC61883_AM824_LABEL_MIDI_NO_DATA)); 
     683                } 
     684                *target_event=tmpval; 
     685                buffer+=8; 
     686            } 
     687        } 
     688        break; 
     689    } 
     690    return 0; 
     691} 
     692 
    731693#endif 
    732694 
     
    758720} 
    759721 
     722int AmdtpTransmitStreamProcessor::encodeSilencePortToMidiEvents ( AmdtpMidiPort *p, quadlet_t *data, 
     723        unsigned int offset, unsigned int nevents ) 
     724{ 
     725    unsigned int j=0; 
     726    unsigned int position = p->getPosition(); 
     727    unsigned int location = p->getLocation(); 
     728 
     729    quadlet_t *target_event; 
     730 
     731    switch ( p->getDataType() ) 
     732    { 
     733        default: 
     734            debugError("bad type: %d\n", p->getDataType()); 
     735            return -1; 
     736        case Port::E_Midi: 
     737        { 
     738            assert(nevents + offset <= p->getBufferSize()); 
     739            for ( j = location; j < nevents; j += 8 ) 
     740            { 
     741                target_event = (quadlet_t *) (data + ((j * m_dimension) + position)); 
     742                *target_event=htonl(IEC61883_AM824_SET_LABEL(0, IEC61883_AM824_LABEL_MIDI_NO_DATA)); 
     743            } 
     744        } 
     745        break; 
     746    } 
     747    return 0; 
     748} 
     749 
    760750} // end of namespace Streaming 
  • branches/api-cleanup/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h

    r750 r809  
    115115                        unsigned int offset); 
    116116 
    117     bool encodePacketPorts(quadlet_t *data, unsigned int nevents, 
    118                            unsigned int dbc); 
    119  
    120117    int encodePortToMBLAEvents(AmdtpAudioPort *, quadlet_t *data, 
    121                                 unsigned int offset, unsigned int nevents); 
     118                               unsigned int offset, unsigned int nevents); 
     119    int encodePortToMidiEvents(AmdtpMidiPort *p, quadlet_t *data, 
     120                               unsigned int offset, unsigned int nevents); 
    122121    int encodeSilencePortToMBLAEvents(AmdtpAudioPort *, quadlet_t *data, 
    123                                 unsigned int offset, unsigned int nevents); 
     122                                      unsigned int offset, unsigned int nevents); 
     123    int encodeSilencePortToMidiEvents(AmdtpMidiPort *p, quadlet_t *data, 
     124                                      unsigned int offset, unsigned int nevents); 
    124125 
    125126    unsigned int getFDF(); 
  • branches/api-cleanup/src/libstreaming/generic/Port.cpp

    r750 r809  
    2323 
    2424#include "Port.h" 
     25#include "PortManager.h" 
    2526 
    2627#include <stdlib.h> 
     
    3132IMPL_DEBUG_MODULE( Port, Port, DEBUG_LEVEL_NORMAL ); 
    3233 
    33 Port::Port(std::string name, enum E_PortType porttype, enum E_Direction direction) 
    34       : m_Name(name), 
    35     m_SignalType(E_PeriodSignalled), 
    36     m_BufferType(E_PointerBuffer), 
    37     m_disabled(true), 
    38     m_buffersize(0), 
    39     m_eventsize(0), 
    40     m_DataType(E_Int24), 
    41     m_PortType(porttype), 
    42     m_Direction(direction), 
    43     m_buffer(0), 
    44     m_ringbuffer(0), 
    45     m_use_external_buffer(false), 
    46     m_do_ratecontrol(false), 
    47     m_event_interval(0), 
    48     m_slot_interval(0), 
    49     m_rate_counter(0), 
    50     m_rate_counter_minimum(0), 
    51     m_average_ratecontrol(false), 
    52     m_State(E_Created) 
     34Port::Port(PortManager& m, std::string name,  
     35           enum E_PortType porttype, enum E_Direction direction, enum E_DataType d) 
     36    : m_Name( name ) 
     37    , m_disabled( true ) 
     38    , m_buffersize( 0 ) 
     39    , m_eventsize( 0 ) 
     40    , m_DataType( d ) 
     41    , m_PortType( porttype ) 
     42    , m_Direction( direction ) 
     43    , m_buffer( NULL ) 
     44    , m_manager( m ) 
     45    , m_State( E_Created ) 
    5346{ 
    54  
     47    m_manager.registerPort(this); 
     48
     49 
     50Port::~Port() { 
     51    m_manager.unregisterPort(this); 
    5552} 
    5653 
     
    7471    } 
    7572 
    76     switch (m_BufferType) { 
    77         case E_PointerBuffer: 
    78             if (m_use_external_buffer) { 
    79                 // don't do anything 
    80             } else if (!allocateInternalBuffer()) { 
    81                 debugFatal("Could not allocate internal buffer!\n"); 
    82                 return false; 
    83             } 
    84             break; 
    85  
    86         case E_RingBuffer: 
    87             if (m_use_external_buffer) { 
    88                 debugFatal("Cannot use an external ringbuffer! \n"); 
    89                 return false; 
    90             } else if (!allocateInternalRingBuffer()) { 
    91                 debugFatal("Could not allocate internal ringbuffer!\n"); 
    92                 return false; 
    93             } 
    94             break; 
    95         default: 
    96             debugFatal("Unsupported buffer type! (%d)\n",(int)m_BufferType); 
    97             return false; 
    98             break; 
    99     } 
    100  
    101     m_eventsize=getEventSize(); // this won't change, so cache it 
    102      
     73    m_eventsize = getEventSize(); // this won't change, so cache it 
     74 
    10375    m_State = E_Initialized; 
    10476    return true; 
     
    10678 
    10779bool Port::reset() { 
    108     if (m_BufferType==E_RingBuffer) { 
    109         ffado_ringbuffer_reset(m_ringbuffer); 
    110     } 
    111     return true; 
    112 }; 
     80    return true; 
     81
    11382 
    11483bool Port::setName(std::string name) { 
     
    138107            return sizeof(float); 
    139108        case E_Int24: // 24 bit 2's complement, packed in a 32bit integer (LSB's) 
     109            return sizeof(int32_t); 
     110        case E_MidiEvent: 
    140111            return sizeof(uint32_t); 
    141         case E_MidiEvent: 
     112        case E_ControlEvent: 
    142113            return sizeof(uint32_t); 
    143114        default: 
     
    164135            break; 
    165136        case E_Control: 
    166             if(d == E_Default) type_is_ok=true; 
     137            if(d == E_ControlEvent) type_is_ok=true; 
    167138            break; 
    168139        default: 
     
    179150} 
    180151 
    181 bool Port::setSignalType(enum E_SignalType s) { 
    182     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting signaltype to %d for port %s\n",(int)s,m_Name.c_str()); 
    183     if (m_State != E_Created) { 
    184         debugFatal("Port (%s) not in E_Created state: %d\n",m_Name.c_str(),m_State); 
    185         return false; 
    186     } 
    187  
    188     // do some sanity checks 
    189     bool type_is_ok=false; 
    190     switch (m_PortType) { 
    191         case E_Audio: 
    192             if(s == E_PeriodSignalled) type_is_ok=true; 
    193             break; 
    194         case E_Midi: 
    195             if(s == E_PacketSignalled) type_is_ok=true; 
    196             break; 
    197         case E_Control: 
    198             if(s == E_PeriodSignalled) type_is_ok=true; 
    199             break; 
    200         default: 
    201             break; 
    202     } 
    203     if(!type_is_ok) { 
    204         debugFatal("Signalling type not supported by this type of port!\n"); 
    205         return false; 
    206     } 
    207     m_SignalType=s; 
    208     return true; 
    209 } 
    210  
    211 bool Port::setBufferType(enum E_BufferType b) { 
    212     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting buffer type to %d for port %s\n",(int)b,m_Name.c_str()); 
    213     if (m_State != E_Created) { 
    214         debugFatal("Port (%s) not in E_Created state: %d\n",m_Name.c_str(),m_State); 
    215         return false; 
    216     } 
    217     // do some sanity checks 
    218     bool type_is_ok=false; 
    219     switch (m_PortType) { 
    220         case E_Audio: 
    221             if(b == E_PointerBuffer) type_is_ok=true; 
    222             break; 
    223         case E_Midi: 
    224             if(b == E_RingBuffer) type_is_ok=true; 
    225             break; 
    226         case E_Control: 
    227             break; 
    228         default: 
    229             break; 
    230     } 
    231     if(!type_is_ok) { 
    232         debugFatal("Buffer type not supported by this type of port!\n"); 
    233         return false; 
    234     } 
    235     m_BufferType=b; 
    236     return true; 
    237 } 
    238  
    239 bool Port::useExternalBuffer(bool b) { 
    240     // If called on an initialised stream but the request isn't for a change silently 
    241     // allow it (relied on by C API as used by jack backend driver) 
    242     if (m_State==E_Initialized && m_use_external_buffer==b) 
    243         return true; 
    244  
    245     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting external buffer use to %d for port %s\n",(int)b,m_Name.c_str()); 
    246  
    247     if (m_State != E_Created) { 
    248         debugFatal("Port (%s) not in E_Created state: %d\n",m_Name.c_str(),m_State); 
    249         return false; 
    250     } 
    251     m_use_external_buffer=b; 
    252     return true; 
    253 } 
    254  
    255152// buffer handling api's for pointer buffers 
    256153/** 
    257  * Get the buffer address (being the external or the internal one). 
     154 * Get the buffer address 
    258155 * 
    259156 * @param buff 
    260157 */ 
    261158void *Port::getBufferAddress() { 
    262     assert(m_BufferType==E_PointerBuffer); 
    263159    return m_buffer; 
    264160}; 
     
    266162/** 
    267163 * Set the external buffer address. 
    268  * only call this when you have specified that you will use 
    269  * an external buffer before doing the init() 
    270164 * 
    271165 * @param buff 
    272166 */ 
    273 void Port::setExternalBufferAddress(void *buff) { 
    274     assert(m_BufferType==E_PointerBuffer); 
    275     assert(m_use_external_buffer); // don't call this with an internal buffer! 
     167void Port::setBufferAddress(void *buff) { 
    276168    m_buffer=buff; 
    277 }; 
    278  
    279 // buffer handling api's for ringbuffers 
    280 bool Port::writeEvent(void *event) { 
    281  
    282 #ifdef DEBUG 
    283     if (m_State != E_Initialized) { 
    284         debugFatal("Port (%s) not in E_Initialized state: %d\n",m_Name.c_str(),m_State); 
    285         return false; 
    286     } 
    287      
    288     if(m_BufferType!=E_RingBuffer) { 
    289         debugError("operation not allowed on non E_RingBuffer ports\n"); 
    290         show(); 
    291         return false; 
    292     } 
    293     assert(m_ringbuffer); 
    294 #endif 
    295  
    296     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Writing event %08X with size %d to port %s\n",*((quadlet_t *)event),m_eventsize, m_Name.c_str()); 
    297  
    298     return (ffado_ringbuffer_write(m_ringbuffer, (char *)event, m_eventsize)==m_eventsize); 
    299 } 
    300  
    301 bool Port::readEvent(void *event) { 
    302  
    303 #ifdef DEBUG 
    304     if (m_State != E_Initialized) { 
    305         debugFatal("Port (%s) not in E_Initialized state: %d\n",m_Name.c_str(),m_State); 
    306         return false; 
    307     } 
    308      
    309     if(m_BufferType!=E_RingBuffer) { 
    310         debugError("operation not allowed on non E_RingBuffer ports\n"); 
    311         show(); 
    312         return false; 
    313     } 
    314     assert(m_ringbuffer); 
    315 #endif 
    316  
    317      
    318     unsigned int read=ffado_ringbuffer_read(m_ringbuffer, (char *)event, m_eventsize); 
    319      
    320     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Reading event %X with size %d from port %s\n",*((quadlet_t *)event),m_eventsize,m_Name.c_str()); 
    321  
    322  
    323     return (read==m_eventsize); 
    324 } 
    325  
    326 int Port::writeEvents(void *event, unsigned int nevents) { 
    327  
    328 #ifdef DEBUG 
    329     if (m_State != E_Initialized) { 
    330         debugFatal("Port (%s) not in E_Initialized state: %d\n",m_Name.c_str(),m_State); 
    331         return false; 
    332     } 
    333      
    334     if(m_BufferType!=E_RingBuffer) { 
    335         debugError("operation not allowed on non E_RingBuffer ports\n"); 
    336         show(); 
    337         return false; 
    338     } 
    339     assert(m_ringbuffer); 
    340 #endif 
    341  
    342  
    343     unsigned int bytes2write=m_eventsize*nevents; 
    344  
    345     unsigned int written=ffado_ringbuffer_write(m_ringbuffer, (char *)event,bytes2write)/m_eventsize; 
    346  
    347 #ifdef DEBUG 
    348     if(written) { 
    349         unsigned int i=0; 
    350         quadlet_t * tmp=(quadlet_t *)event; 
    351         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Written %d events (",written); 
    352         for (i=0;i<written;i++) { 
    353             debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "%X ", *(tmp+i)); 
    354         } 
    355         debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, ") to port %s\n",m_Name.c_str()); 
    356     } 
    357 #endif 
    358  
    359     return written; 
    360  
    361 } 
    362  
    363 int Port::readEvents(void *event, unsigned int nevents) { 
    364  
    365 #ifdef DEBUG 
    366     if (m_State != E_Initialized) { 
    367         debugFatal("Port (%s) not in E_Initialized state: %d\n",m_Name.c_str(),m_State); 
    368         return false; 
    369     } 
    370     if(m_BufferType!=E_RingBuffer) { 
    371         debugError("operation not allowed on non E_RingBuffer ports\n"); 
    372         show(); 
    373         return false; 
    374     } 
    375     assert(m_ringbuffer); 
    376 #endif 
    377  
    378  
    379     unsigned int bytes2read=m_eventsize*nevents; 
    380  
    381     unsigned int read=ffado_ringbuffer_read(m_ringbuffer, (char *)event, bytes2read)/m_eventsize; 
    382  
    383 #ifdef DEBUG 
    384     if(read) { 
    385         unsigned int i=0; 
    386         quadlet_t * tmp=(quadlet_t *)event; 
    387         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Read %d events (",read); 
    388         for (i=0;i<read;i++) { 
    389             debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "%X ", *(tmp+i)); 
    390         } 
    391         debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, ") from port %s\n",m_Name.c_str()); 
    392     } 
    393 #endif 
    394  
    395     return read; 
    396 } 
    397  
    398 /* rate control */ 
    399 bool Port::canRead() { 
    400     bool byte_present_in_buffer; 
    401  
    402     bool retval=false; 
    403  
    404     assert(m_ringbuffer); 
    405  
    406     byte_present_in_buffer=(ffado_ringbuffer_read_space(m_ringbuffer) >= m_eventsize); 
    407  
    408     if(byte_present_in_buffer) { 
    409  
    410         if(!m_do_ratecontrol) { 
    411             return true; 
    412         } 
    413  
    414         if(m_rate_counter <= 0) { 
    415             // update the counter 
    416             if(m_average_ratecontrol) { 
    417                 m_rate_counter += m_event_interval; 
    418                 assert(m_rate_counter<m_event_interval); 
    419             } else { 
    420                 m_rate_counter = m_event_interval; 
    421             } 
    422  
    423             retval=true; 
    424         } else { 
    425             debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Rate limit (%s)! rate_counter=%d \n",m_Name.c_str(),m_rate_counter); 
    426  
    427         } 
    428     } 
    429  
    430  
    431     m_rate_counter -= m_slot_interval; 
    432  
    433     // we have to limit the decrement of the ratecounter somehow. 
    434     // m_rate_counter_minimum is initialized when enabling ratecontrol 
    435     if(m_rate_counter < m_rate_counter_minimum) { 
    436         m_rate_counter = m_rate_counter_minimum; 
    437     } 
    438  
    439     return retval; 
    440 } 
    441  
    442 bool Port::useRateControl(bool use, unsigned int slot_interval, 
    443                                 unsigned int event_interval, bool average) { 
    444  
    445     if (use) { 
    446         debugOutput(DEBUG_LEVEL_VERBOSE, "Enabling rate control for port %s...\n",m_Name.c_str()); 
    447         if(slot_interval>event_interval) { 
    448             debugWarning("Rate control not needed!\n",m_Name.c_str()); 
    449             m_do_ratecontrol=false; 
    450             return false; 
    451         } 
    452         if(slot_interval==0) { 
    453             debugFatal("Cannot have slot interval == 0!\n"); 
    454             m_do_ratecontrol=false; 
    455             return false; 
    456         } 
    457         if(event_interval==0) { 
    458             debugFatal("Cannot have event interval == 0!\n"); 
    459             m_do_ratecontrol=false; 
    460             return false; 
    461         } 
    462         m_do_ratecontrol=use; 
    463         m_event_interval=event_interval; 
    464         m_slot_interval=slot_interval; 
    465         m_rate_counter=0; 
    466  
    467         // NOTE: pretty arbitrary, but in average mode this limits the peak stream rate 
    468         m_rate_counter_minimum=-(2*event_interval); 
    469  
    470         m_average_ratecontrol=average; 
    471  
    472     } else { 
    473         debugOutput(DEBUG_LEVEL_VERBOSE, "Disabling rate control for port %s...\n",m_Name.c_str()); 
    474         m_do_ratecontrol=use; 
    475     } 
    476     return true; 
    477169} 
    478170 
     
    482174    debugOutput(DEBUG_LEVEL_VERBOSE, "Enabling port %s...\n",m_Name.c_str()); 
    483175    m_disabled=false; 
    484 }; 
     176} 
    485177 
    486178/// Disable the port. (this can be called anytime) 
     
    489181    debugOutput(DEBUG_LEVEL_VERBOSE, "Disabling port %s...\n",m_Name.c_str()); 
    490182    m_disabled=false; 
    491 }; 
    492  
    493  
    494 /* Private functions */ 
    495  
    496 bool Port::allocateInternalBuffer() { 
    497     int event_size=getEventSize(); 
    498  
    499     debugOutput(DEBUG_LEVEL_VERBOSE, 
    500                 "Allocating internal buffer of %d events with size %d (%s)\n", 
    501                 m_buffersize, event_size, m_Name.c_str()); 
    502  
    503     if(m_buffer) { 
    504         debugWarning("already has an internal buffer attached, re-allocating\n"); 
    505         freeInternalBuffer(); 
    506     } 
    507  
    508     m_buffer=calloc(m_buffersize,event_size); 
    509     if (!m_buffer) { 
    510         debugFatal("could not allocate internal buffer\n"); 
    511         m_buffersize=0; 
    512         return false; 
    513     } 
    514  
    515     return true; 
    516 } 
    517  
    518 void Port::freeInternalBuffer() { 
    519     debugOutput(DEBUG_LEVEL_VERBOSE, 
    520                 "Freeing internal buffer (%s)\n",m_Name.c_str()); 
    521  
    522     if(m_buffer) { 
    523         free(m_buffer); 
    524         m_buffer=0; 
    525     } 
    526 } 
    527  
    528 bool Port::allocateInternalRingBuffer() { 
    529     int event_size=getEventSize(); 
    530  
    531     debugOutput(DEBUG_LEVEL_VERBOSE, 
    532                 "Allocating internal buffer of %d events with size %d (%s)\n", 
    533                 m_buffersize, event_size, m_Name.c_str()); 
    534  
    535     if(m_ringbuffer) { 
    536         debugWarning("already has an internal ringbuffer attached, re-allocating\n"); 
    537         freeInternalRingBuffer(); 
    538     } 
    539  
    540     m_ringbuffer=ffado_ringbuffer_create(m_buffersize * event_size); 
    541     if (!m_ringbuffer) { 
    542         debugFatal("could not allocate internal ringbuffer\n"); 
    543         m_buffersize=0; 
    544         return false; 
    545     } 
    546  
    547     return true; 
    548 } 
    549  
    550 void Port::freeInternalRingBuffer() { 
    551     debugOutput(DEBUG_LEVEL_VERBOSE, 
    552                 "Freeing internal ringbuffer (%s)\n",m_Name.c_str()); 
    553  
    554     if(m_ringbuffer) { 
    555         ffado_ringbuffer_free(m_ringbuffer); 
    556         m_ringbuffer=0; 
    557     } 
    558183} 
    559184 
    560185void Port::show() { 
    561186    debugOutput(DEBUG_LEVEL_VERBOSE,"Name          : %s\n", m_Name.c_str()); 
    562     debugOutput(DEBUG_LEVEL_VERBOSE,"Signal Type   : %d\n", m_SignalType); 
    563     debugOutput(DEBUG_LEVEL_VERBOSE,"Buffer Type   : %d\n", m_BufferType); 
    564187    debugOutput(DEBUG_LEVEL_VERBOSE,"Enabled?      : %d\n", m_disabled); 
    565188    debugOutput(DEBUG_LEVEL_VERBOSE,"State?        : %d\n", m_State); 
     
    569192    debugOutput(DEBUG_LEVEL_VERBOSE,"Port Type     : %d\n", m_PortType); 
    570193    debugOutput(DEBUG_LEVEL_VERBOSE,"Direction     : %d\n", m_Direction); 
    571     debugOutput(DEBUG_LEVEL_VERBOSE,"Rate Control? : %d\n", m_do_ratecontrol); 
    572194} 
    573195 
  • branches/api-cleanup/src/libstreaming/generic/Port.h

    r742 r809  
    3333 
    3434namespace Streaming { 
     35class PortManager; 
    3536 
    3637/*! 
     
    5354       OK. 
    5455 
    55  \todo rework the implementation into something more beautifull 
    5656*/ 
    5757class Port { 
    5858 
    5959public: 
    60     friend class PortManager; 
    61  
    62     /* 
    63      * IMPORTANT: if you add something to any of these enum's, be sure to 
    64      *            check the code where they are used. 
    65      */ 
    66  
    67     /*! 
    68     \brief Specifies the buffer type for ports 
    69  
    70     A PointerBuffer uses the getBufferAddress() and setBufferAddres() interface 
    71     A Ringbuffer uses the read/write interface 
    72     */ 
    73     enum E_BufferType { 
    74         E_PointerBuffer, 
    75         E_RingBuffer 
    76     }; 
    77  
    78     /*! 
    79     \brief Specifies the signalling type for ports 
    80     */ 
    81     enum E_SignalType { 
    82         E_PacketSignalled, ///< the port is to be processed for every packet 
    83         E_PeriodSignalled, ///< the port is to be processed after a period of frames 
    84 //         E_SampleSignalled ///< the port is to be processed after each frame (sample) 
    85     }; 
    86  
    8760    /*! 
    8861    \brief The datatype of the port buffer 
     
    9265        E_Int24, 
    9366        E_MidiEvent, 
    94         E_Default, 
     67        E_ControlEvent, 
    9568    }; 
    9669 
     
    11285    }; 
    11386 
    114     Port(std::string name, enum E_PortType porttype, enum E_Direction direction); 
    115  
    116     virtual ~Port() 
    117       {}; 
     87    Port(PortManager&, std::string name, enum E_PortType, enum E_Direction, enum E_DataType); 
     88 
     89    virtual ~Port(); 
    11890 
    11991 
     
    151123    enum E_DataType getDataType() {return m_DataType;}; 
    152124 
    153     /** 
    154      * \brief sets the event type for the port buffer 
    155      * 
    156      * \note use before calling init() 
    157      */ 
    158     virtual bool setSignalType(enum E_SignalType ); 
    159  
    160     enum E_SignalType getSignalType() {return m_SignalType;}; ///< returns the signalling type of the port 
    161  
    162     /** 
    163      * \brief sets the buffer type for the port 
    164      * 
    165      * \note use before calling init() 
    166      */ 
    167     virtual bool setBufferType(enum E_BufferType ); 
    168  
    169     enum E_BufferType getBufferType() {return m_BufferType;}; ///< returns the buffer type of the port 
    170  
    171125    enum E_PortType getPortType() {return m_PortType;}; ///< returns the port type (is fixed) 
    172126    enum E_Direction getDirection() {return m_Direction;}; ///< returns the direction (is fixed) 
     
    193147    virtual bool setBufferSize(unsigned int); 
    194148 
    195     /** 
    196      * \brief use an external buffer (or not) 
    197      * 
    198      * \note use before calling init() 
    199      */ 
    200     virtual bool useExternalBuffer(bool b); 
    201  
    202     void setExternalBufferAddress(void *buff); 
    203  
    204  
    205     /** 
    206      * \brief enable/disable ratecontrol 
    207      * 
    208      * Rate control is nescessary for some types of ports (most notably 
    209      * midi). The StreamProcessor that handles the port should call canRead() 
    210      * everytime a 'slot' that could be filled with an event passes. The canRead 
    211      * function will return true if 
    212      *  (1) there is an event ready in the buffer 
    213      *  (2) we are allowed to send an event in this slot 
    214      * 
    215      * Setting the rate works is done with the slot_interval and the event_interval 
    216      * parameters. On every call to canRead(), a counter is decremented with 
    217      * slot_interval. If the counter drops below 0, canRead() returns true and resets 
    218      * the counter to event_interval. 
    219      * 
    220      * e.g. for AMDTP midi, we are only allowed to send a midi byte every 320us 
    221      *      if the SYT interval is 8, there is exactly one midi slot every packet. 
    222      *    therefore the slot_interval is 1/8000s (=125us), and the event_interval 
    223      *      is 320us. 
    224      * 
    225      *      Note that the interval parameters are unitless, so you can adapt them 
    226      *      to your needs. In the AMDTP case for example, when the SYT interval is 32 
    227      *      (when the samplerate is 192kHz for example) there are 4 midi slots in 
    228      *      each packet, making the slot time interval 125us/4 = 31.25us. 
    229      *      The event time interval stays the same (320us). We can however set the 
    230      *    slot_interval to 3125 and the event_interval to 32000, as we can choose 
    231      *    the unit of the counter time step (chosen to be 10ns in this case). 
    232      * 
    233      * The average argument deserves some attention too. If average is true, we use 
    234      * average rate control. This means that on average there will be a delay of 
    235      * event_interval between two events, but that sometimes there can be a smaller 
    236      * delay. This mode fixes the average rate of the stream. 
    237      * If average is false, there will always be a minimal delay of event_interval 
    238      * between two events. This means that the maximum rate of the stream is fixed, 
    239      * and that the average rate will be lower than (or at max equal to) the rate in 
    240      * average mode. 
    241      * 
    242      * 
    243      * \note only works for the E_RingBuffer ports 
    244      * \note use before calling init() 
    245      * 
    246      * @param use set this to true to use rate control 
    247      * @param slot_interval the interval between slots 
    248      * @param event_interval the interval between events 
    249      * @param average use average rate control 
    250      * @return true if rate control was enabled/disabled successfully 
    251      */ 
    252     virtual bool useRateControl(bool use, unsigned int slot_interval, 
    253                                 unsigned int event_interval, bool average); 
    254  
    255     bool usingRateControl() { return m_do_ratecontrol;}; ///< are we using rate control? 
    256  
    257     /** 
    258      * Can we send an event in this slot. subject to rate control and 
    259      * byte availability. 
    260      * @return true if we can send an event on this slot 
    261      */ 
    262     bool canRead(); 
    263  
    264     // FIXME: this is not really OO, but for performance??? 
     149    void setBufferAddress(void *buff); 
    265150    void *getBufferAddress(); 
    266151 
    267     // TODO: extend this with a blocking interface 
    268     bool writeEvent(void *event); ///< write one event 
    269     bool readEvent(void *event); ///< read one event 
    270     int writeEvents(void *event, unsigned int nevents); ///< write multiple events 
    271     int readEvents(void *event, unsigned int nevents); ///< read multiple events 
     152    PortManager& getManager() { return m_manager; }; 
    272153 
    273154    virtual void setVerboseLevel(int l); 
    274155    virtual void show(); 
    275      
     156 
    276157protected: 
    277158    std::string m_Name; ///< Port name, [at construction] 
    278  
    279     enum E_SignalType m_SignalType; ///< Signalling type, [at construction] 
    280     enum E_BufferType m_BufferType; ///< Buffer type, [at construction] 
    281  
    282159    bool m_disabled; ///< is the port disabled?, [anytime] 
    283160 
     
    290167 
    291168    void *m_buffer; 
    292     ffado_ringbuffer_t *m_ringbuffer; 
    293     bool m_use_external_buffer; 
    294  
    295     bool m_do_ratecontrol; 
    296     int m_event_interval; 
    297     int m_slot_interval; 
    298     int m_rate_counter; 
    299     int m_rate_counter_minimum; 
    300     bool m_average_ratecontrol; 
    301  
    302     bool allocateInternalBuffer(); 
    303     void freeInternalBuffer(); 
    304  
    305     bool allocateInternalRingBuffer(); 
    306     void freeInternalRingBuffer(); 
     169     
     170    PortManager& m_manager; 
    307171 
    308172    DECLARE_DEBUG_MODULE; 
    309      
    310     // the state machine 
    311     protected: 
    312         enum EStates { 
    313             E_Created, 
    314             E_Initialized, 
    315             E_Prepared, 
    316             E_Running, 
    317             E_Error 
    318         }; 
    319  
    320         enum EStates m_State; 
     173 
     174// the state machine 
     175protected: 
     176    enum EStates { 
     177        E_Created, 
     178        E_Initialized, 
     179        E_Prepared, 
     180        E_Running, 
     181        E_Error 
     182    }; 
     183 
     184    enum EStates m_State; 
    321185}; 
    322186 
     
    330194public: 
    331195 
    332     AudioPort(std::string name, enum E_Direction direction) 
    333       : Port(name, E_Audio, direction
     196    AudioPort(PortManager& m, std::string name, enum E_Direction direction) 
     197      : Port(m, name, E_Audio, direction, E_Int24
    334198    {}; 
    335199 
    336200    virtual ~AudioPort() {}; 
    337  
    338 protected: 
    339  
    340  
    341201}; 
    342202 
     
    350210public: 
    351211 
    352     MidiPort(std::string name, enum E_Direction direction) 
    353       : Port(name, E_Midi, direction
     212    MidiPort(PortManager& m, std::string name, enum E_Direction direction) 
     213      : Port(m, name, E_Midi, direction, E_MidiEvent
    354214    {}; 
    355215    virtual ~MidiPort() {}; 
    356  
    357  
    358 protected: 
    359  
    360  
    361216}; 
    362217 
     
    370225public: 
    371226 
    372     ControlPort(std::string name, enum E_Direction direction) 
    373       : Port(name, E_Control, direction
     227    ControlPort(PortManager& m, std::string name, enum E_Direction direction) 
     228      : Port(m, name, E_Control, direction, E_ControlEvent
    374229    {}; 
    375230    virtual ~ControlPort() {}; 
    376  
    377  
    378 protected: 
    379  
    380  
    381231}; 
    382232 
  • branches/api-cleanup/src/libstreaming/generic/PortManager.cpp

    r750 r809  
    4040 
    4141PortManager::~PortManager() { 
    42 //     deleteAllPorts(); 
    43 
    44  
    45 // bool PortManager::setPortBuffersize(unsigned int newsize) { 
    46 //     debugOutput( DEBUG_LEVEL_VERBOSE, "setting port buffer size to %d\n",newsize); 
    47 // 
    48 // 
    49 //     for ( PortVectorIterator it = m_Ports.begin(); 
    50 //       it != m_Ports.end(); 
    51 //       ++it ) 
    52 //     { 
    53 //         if(!(*it)->setBufferSize(newsize)) { 
    54 //             debugFatal("Could not set buffer size for port %s\n",(*it)->getName().c_str()); 
    55 //             return false; 
    56 //         } 
    57 //     } 
    58 // 
    59 //     return true; //not found 
    60 // 
    61 // } 
     42    // delete all ports that are still registered to the manager 
     43    for ( PortVectorIterator it = m_Ports.begin(); 
     44    it != m_Ports.end(); 
     45    ++it ) 
     46    { 
     47        delete *it; 
     48    } 
     49
    6250 
    6351bool PortManager::makeNameUnique(Port *port) 
     
    9684 * @return 
    9785 */ 
    98 bool PortManager::addPort(Port *port) 
     86bool PortManager::registerPort(Port *port) 
    9987{ 
    10088    assert(port); 
     
    113101} 
    114102 
    115 bool PortManager::deletePort(Port *port) 
     103bool PortManager::unregisterPort(Port *port) 
    116104{ 
    117105    assert(port); 
     
    124112        if(*it == port) { 
    125113            m_Ports.erase(it); 
    126 //             delete *it; 
    127114            return true; 
    128115        } 
     
    132119 
    133120    return false; //not found 
    134  
    135 } 
    136  
    137 void PortManager::deleteAllPorts() 
    138 { 
    139     debugOutput( DEBUG_LEVEL_VERBOSE, "deleting all ports\n"); 
    140  
    141     for ( PortVectorIterator it = m_Ports.begin(); 
    142       it != m_Ports.end(); 
    143       ++it ) 
    144     { 
    145         m_Ports.erase(it); 
    146 //         delete *it; 
    147     } 
    148  
    149     return; 
    150121 
    151122} 
     
    213184    { 
    214185        if(!(*it)->init()) { 
    215             debugFatal("Could not init port %s",(*it)->getName().c_str()); 
     186            debugFatal("Could not init port %s\n", (*it)->getName().c_str()); 
    216187            return false; 
    217188        } 
     
    222193bool PortManager::preparePorts() { 
    223194    debugOutput( DEBUG_LEVEL_VERBOSE, "preparing ports\n"); 
    224  
    225     // clear the cache lists 
    226     m_PeriodPorts.clear(); 
    227     m_PacketPorts.clear(); 
    228195 
    229196    for ( PortVectorIterator it = m_Ports.begin(); 
     
    236203        } 
    237204 
    238         // now prepare the cache lists 
    239         switch((*it)->getSignalType()) { 
    240             case Port::E_PacketSignalled: 
    241                 m_PacketPorts.push_back(*it); 
    242                 break; 
    243             case Port::E_PeriodSignalled: 
    244                 m_PeriodPorts.push_back(*it); 
    245                 break; 
    246             default: 
    247                 debugWarning("%s has unsupported port type\n", 
    248                              (*it)->getName().c_str()); 
    249             break; 
    250         } 
    251205    } 
    252206    return true; 
  • branches/api-cleanup/src/libstreaming/generic/PortManager.h

    r742 r809  
    3333namespace Streaming { 
    3434 
    35 class Port; 
    3635typedef std::vector<Port *> PortVector; 
    3736typedef std::vector<Port *>::iterator PortVectorIterator; 
     
    5049 
    5150    virtual bool makeNameUnique(Port *port); 
    52     virtual bool addPort(Port *port); 
    53     virtual bool deletePort(Port *port); 
    54     virtual void deleteAllPorts(); 
     51    virtual bool registerPort(Port *port); 
     52    virtual bool unregisterPort(Port *port); 
    5553 
    5654    int getPortCount(enum Port::E_PortType); 
    5755    int getPortCount(); 
    58  
    59 //     virtual bool setPortBuffersize(unsigned int newsize); 
    6056 
    6157    Port *getPortAtIdx(unsigned int index); 
     
    6965protected: 
    7066    PortVector m_Ports; 
    71     PortVector m_PacketPorts; 
    72     PortVector m_PeriodPorts; 
    73 //     PortVector m_SamplePorts; 
    7467 
    7568    DECLARE_DEBUG_MODULE; 
    76  
    7769}; 
    7870 
  • branches/api-cleanup/src/libstreaming/generic/StreamProcessor.cpp

    r807 r809  
    960960{ 
    961961    bool no_problem=true; 
    962     for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    963           it != m_PeriodPorts.end(); 
     962    for ( PortVectorIterator it = m_Ports.begin(); 
     963          it != m_Ports.end(); 
    964964          ++it ) { 
    965965        if((*it)->isDisabled()) {continue;}; 
    966966 
    967         //FIXME: make this into a static_cast when not DEBUG? 
    968         Port *port=dynamic_cast<Port *>(*it); 
    969  
    970         switch(port->getPortType()) { 
    971  
    972         case Port::E_Audio: 
    973             if(provideSilenceToPort(static_cast<AudioPort *>(*it), offset, nevents)) { 
    974                 debugWarning("Could not put silence into to port %s",(*it)->getName().c_str()); 
    975                 no_problem=false; 
    976             } 
    977             break; 
    978         // midi is a packet based port, don't process 
    979         //    case MotuPortInfo::E_Midi: 
    980         //        break; 
    981  
    982         default: // ignore 
    983             break; 
     967        if(provideSilenceToPort((*it), offset, nevents)) { 
     968            debugWarning("Could not put silence into to port %s",(*it)->getName().c_str()); 
     969            no_problem=false; 
    984970        } 
    985971    } 
     
    988974 
    989975int 
    990 StreamProcessor::provideSilenceToPort( 
    991                        AudioPort *p, unsigned int offset, unsigned int nevents) 
     976StreamProcessor::provideSilenceToPort(Port *p, unsigned int offset, unsigned int nevents) 
    992977{ 
    993978    unsigned int j=0; 
    994979    switch(p->getDataType()) { 
    995980        default: 
     981            debugError("Invalid port type: %d\n", p->getDataType()); 
     982            return -1; 
    996983        case Port::E_Int24: 
     984        case Port::E_MidiEvent: 
     985        case Port::E_ControlEvent: 
    997986            { 
    998987                quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress()); 
     
    1000989                buffer+=offset; 
    1001990 
    1002                 for(j = 0; j < nevents; j += 1) { // decode max nsamples 
     991                for(j = 0; j < nevents; j += 1) { 
    1003992                    *(buffer)=0; 
    1004993                    buffer++; 
     
    10121001                buffer+=offset; 
    10131002 
    1014                 for(j = 0; j < nevents; j += 1) { // decode max nsamples 
     1003                for(j = 0; j < nevents; j += 1) { 
    10151004                    *buffer = 0.0; 
    10161005                    buffer++; 
     
    13201309                    return false; 
    13211310                } 
    1322                 switch ((*it)->getPortType()) { 
    1323                     case Port::E_Audio: 
    1324                         if(!(*it)->setSignalType(Port::E_PeriodSignalled)) { 
    1325                             debugFatal("Could not set signal type to PeriodSignalling"); 
    1326                             return false; 
    1327                         } 
    1328                         // buffertype and datatype are dependant on the API 
    1329                         debugWarning("---------------- ! Doing hardcoded dummy setup ! --------------\n"); 
    1330                         // buffertype and datatype are dependant on the API 
    1331                         if(!(*it)->setBufferType(Port::E_PointerBuffer)) { 
    1332                             debugFatal("Could not set buffer type"); 
    1333                             return false; 
    1334                         } 
    1335                         if(!(*it)->useExternalBuffer(true)) { 
    1336                             debugFatal("Could not set external buffer usage"); 
    1337                             return false; 
    1338                         } 
    1339                         if(!(*it)->setDataType(Port::E_Float)) { 
    1340                             debugFatal("Could not set data type"); 
    1341                             return false; 
    1342                         } 
    1343                         break; 
    1344                     case Port::E_Midi: 
    1345                         if(!(*it)->setSignalType(Port::E_PacketSignalled)) { 
    1346                             debugFatal("Could not set signal type to PacketSignalling"); 
    1347                             return false; 
    1348                         } 
    1349                         // buffertype and datatype are dependant on the API 
    1350                         debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n"); 
    1351                         // buffertype and datatype are dependant on the API 
    1352                         if(!(*it)->setBufferType(Port::E_RingBuffer)) { 
    1353                             debugFatal("Could not set buffer type"); 
    1354                             return false; 
    1355                         } 
    1356                         if(!(*it)->setDataType(Port::E_MidiEvent)) { 
    1357                             debugFatal("Could not set data type"); 
    1358                             return false; 
    1359                         } 
    1360                         break; 
    1361                     default: 
    1362                         debugWarning("Unsupported port type specified\n"); 
    1363                         break; 
    1364                 } 
    13651311            } 
    13661312            // the API specific settings of the ports should already be set, 
  • branches/api-cleanup/src/libstreaming/generic/StreamProcessor.h

    r807 r809  
    292292        {debugWarning("call not allowed\n"); return false;}; 
    293293protected: // some generic helpers 
    294     int provideSilenceToPort(AudioPort *p, unsigned int offset, unsigned int nevents); 
     294    int provideSilenceToPort(Port *p, unsigned int offset, unsigned int nevents); 
    295295    bool provideSilenceBlock(unsigned int nevents, unsigned int offset); 
    296296 
  • branches/api-cleanup/src/libstreaming/motu/MotuPort.h

    r742 r809  
    4848public: 
    4949 
    50     MotuAudioPort(std::string name, 
    51                        enum E_Direction direction, 
    52                    int position, 
    53                    int size) 
    54     : AudioPort(name, direction), 
     50    MotuAudioPort(PortManager &m, 
     51                  std::string name, 
     52                  enum E_Direction direction, 
     53                  int position, 
     54                  int size) 
     55    : AudioPort(m, name, direction), 
    5556      MotuPortInfo( position, size) // TODO: add more port information parameters here if nescessary 
    5657    {}; 
    5758 
    5859    virtual ~MotuAudioPort() {}; 
    59  
    60 protected: 
    61  
    6260}; 
    6361 
     
    7371public: 
    7472 
    75     MotuMidiPort(std::string name, 
    76                        enum E_Direction direction, 
    77                    int position) 
    78         : MidiPort(name, direction), 
     73    MotuMidiPort(PortManager &m, 
     74                 std::string name, 
     75                 enum E_Direction direction, 
     76                 int position) 
     77        : MidiPort(m, name, direction), 
    7978          MotuPortInfo(position, 0)  // TODO: add more port information parameters here if nescessary 
    8079    {}; 
    8180 
    82  
    8381    virtual ~MotuMidiPort() {}; 
    84  
    85 protected: 
    86  
    8782}; 
    8883 
     
    9893public: 
    9994 
    100     MotuControlPort(std::string name, 
    101                        enum E_Direction direction, 
    102                    int position) 
    103         : ControlPort(name, direction), 
     95    MotuControlPort(PortManager &m, 
     96                    std::string name, 
     97                    enum E_Direction direction, 
     98                    int position) 
     99        : ControlPort(m, name, direction), 
    104100          MotuPortInfo(position, 2) // TODO: add more port information parameters here if nescessary 
    105101    {}; 
    106102 
    107  
    108103    virtual ~MotuControlPort() {}; 
    109  
    110 protected: 
    111  
    112104}; 
    113105 
  • branches/api-cleanup/src/libstreaming/motu/MotuReceiveStreamProcessor.cpp

    r750 r809  
    187187 
    188188    if(m_data_buffer->writeFrames(n_events, (char *)(data+8), m_last_timestamp)) { 
    189         int dbc = get_bits(ntohl(quadlet[0]), 8, 8); 
    190         // process all ports that should be handled on a per-packet base 
    191         // this is MIDI for AMDTP (due to the need of DBC) 
    192         if(isRunning()) { 
    193             if (!decodePacketPorts((quadlet_t *)(data+8), n_events, dbc)) { 
    194                 debugWarning("Problem decoding Packet Ports\n"); 
    195             } 
    196         } 
    197189        return eCRV_OK; 
    198190    } else { 
     
    211203{ 
    212204    bool no_problem=true; 
    213     for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    214           it != m_PeriodPorts.end(); 
     205    for ( PortVectorIterator it = m_Ports.begin(); 
     206          it != m_Ports.end(); 
    215207          ++it ) { 
    216208        if((*it)->isDisabled()) {continue;}; 
    217209 
    218         //FIXME: make this into a static_cast when not DEBUG? 
    219         Port *port=dynamic_cast<Port *>(*it); 
     210        Port *port=(*it); 
    220211 
    221212        switch(port->getPortType()) { 
     
    227218            } 
    228219            break; 
    229         // midi is a packet based port, don't process 
    230         //    case MotuPortInfo::E_Midi: 
    231         //        break; 
     220        case Port::E_Midi: 
     221//             if(decodeMotuMidiEventsToPort(static_cast<MotuMidiPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
     222//                 debugWarning("Could not decode packet midi data to port %s",(*it)->getName().c_str()); 
     223//                 no_problem=false; 
     224//             } 
     225            break; 
    232226 
    233227        default: // ignore 
     
    236230    } 
    237231    return no_problem; 
    238 } 
    239  
    240 /** 
    241  * @brief decode a packet for the packet-based ports 
    242  * 
    243  * @param data Packet data 
    244  * @param nevents number of events in data (including events of other ports & port types) 
    245  * @param dbc DataBlockCount value for this packet 
    246  * @return true if all successfull 
    247  */ 
    248 bool MotuReceiveStreamProcessor::decodePacketPorts(quadlet_t *data, unsigned int nevents, 
    249         unsigned int dbc) { 
    250     bool ok=true; 
    251  
    252     // Use char here since the source address won't necessarily be 
    253     // aligned; use of an unaligned quadlet_t may cause issues on 
    254     // certain architectures.  Besides, the source for MIDI data going 
    255     // directly to the MOTU isn't structured in quadlets anyway; it is a 
    256     // sequence of 3 unaligned bytes. 
    257     unsigned char *src = NULL; 
    258  
    259     for ( PortVectorIterator it = m_PacketPorts.begin(); 
    260         it != m_PacketPorts.end(); 
    261         ++it ) { 
    262  
    263         Port *port=dynamic_cast<Port *>(*it); 
    264         assert(port); // this should not fail!! 
    265  
    266         // Currently the only packet type of events for MOTU 
    267         // is MIDI in mbla.  However in future control data 
    268         // might also be sent via "packet" events, so allow 
    269         // for this possible expansion. 
    270  
    271         // FIXME: MIDI input is completely untested at present. 
    272         switch (port->getPortType()) { 
    273             case Port::E_Midi: { 
    274                 MotuMidiPort *mp=static_cast<MotuMidiPort *>(*it); 
    275                 signed int sample; 
    276                 unsigned int j = 0; 
    277                 // Get MIDI bytes if present anywhere in the 
    278                 // packet.  MOTU MIDI data is sent using a 
    279                 // 3-byte sequence starting at the port's 
    280                 // position.  It's thought that there can never 
    281                 // be more than one MIDI byte per packet, but 
    282                 // for completeness we'll check the entire packet 
    283                 // anyway. 
    284                 src = (unsigned char *)data + mp->getPosition(); 
    285                 while (j < nevents) { 
    286                     if (*src==0x01 && *(src+1)==0x00) { 
    287                         sample = *(src+2); 
    288                         if (!mp->writeEvent(&sample)) { 
    289                             debugWarning("MIDI packet port events lost\n"); 
    290                             ok = false; 
    291                         } 
    292                     } 
    293                     j++; 
    294                     src += m_event_size; 
    295                 } 
    296                 break; 
    297             } 
    298             default: 
    299                 debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown packet-type port format %d\n",port->getPortType()); 
    300                 return ok; 
    301               } 
    302     } 
    303  
    304     return ok; 
    305232} 
    306233 
  • branches/api-cleanup/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp

    r798 r809  
    6262{} 
    6363 
    64  
    6564unsigned int 
    6665MotuTransmitStreamProcessor::getMaxPacketSize() { 
     
    310309        } 
    311310 
    312         // Process all ports that should be handled on a per-packet base 
    313         // this is MIDI for AMDTP (due to the need of DBC, which is lost 
    314         // when putting the events in the ringbuffer) 
    315         // for motu this might also be control data, however as control 
    316         // data isn't time specific I would also include it in the period 
    317         // based processing 
    318  
    319         // FIXME: m_tx_dbc probably needs to be initialised to a non-zero 
    320         // value somehow so MIDI sync is possible.  For now we ignore 
    321         // this issue. 
    322         if (!encodePacketPorts((quadlet_t *)(data+8), n_events, m_tx_dbc)) { 
    323             debugWarning("Problem encoding Packet Ports\n"); 
    324         } 
    325  
    326311        return eCRV_OK; 
    327312    } 
     
    403388{ 
    404389    debugOutput ( DEBUG_LEVEL_VERBOSE, "Preparing (%p)...\n", this ); 
    405  
    406  
    407 #if 0 
    408     for ( PortVectorIterator it = m_Ports.begin(); 
    409             it != m_Ports.end(); 
    410             ++it ) 
    411     { 
    412         if ( ( *it )->getPortType() == Port::E_Midi ) 
    413         { 
    414             // we use a timing unit of 10ns 
    415             // this makes sure that for the max syt interval 
    416             // we don't have rounding, and keeps the numbers low 
    417             // we have 1 slot every 8 events 
    418             // we have syt_interval events per packet 
    419             // => syt_interval/8 slots per packet 
    420             // packet rate is 8000pkt/sec => interval=125us 
    421             // so the slot interval is (1/8000)/(syt_interval/8) 
    422             // or: 1/(1000 * syt_interval) sec 
    423             // which is 1e9/(1000*syt_interval) nsec 
    424             // or 100000/syt_interval 'units' 
    425             // the event interval is fixed to 320us = 32000 'units' 
    426             if ( ! ( *it )->useRateControl ( true, ( 100000/m_syt_interval ),32000, false ) ) 
    427             { 
    428                 debugFatal ( "Could not set signal type to PeriodSignalling" ); 
    429                 return false; 
    430             } 
    431             break; 
    432         } 
    433     } 
    434 #endif 
    435390    return true; 
    436391} 
     
    450405    } 
    451406 
    452     for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    453       it != m_PeriodPorts.end(); 
     407    for ( PortVectorIterator it = m_Ports.begin(); 
     408      it != m_Ports.end(); 
    454409      ++it ) { 
    455410        // If this port is disabled, don't process it 
    456411        if((*it)->isDisabled()) {continue;}; 
    457412 
    458         //FIXME: make this into a static_cast when not DEBUG? 
    459         Port *port=dynamic_cast<Port *>(*it); 
     413        Port *port=(*it); 
    460414 
    461415        switch(port->getPortType()) { 
     
    463417        case Port::E_Audio: 
    464418            if (encodePortToMotuEvents(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
    465                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str()); 
     419                debugWarning("Could not encode port %s to Motu events",(*it)->getName().c_str()); 
    466420                no_problem=false; 
    467421            } 
    468422            break; 
    469         // midi is a packet based port, don't process 
    470         //    case MotuPortInfo::E_Midi: 
    471         //        break; 
    472  
     423        case Port::E_Midi: 
     424//             if (encodePortToMotuMidiEvents(static_cast<MotuMidiPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
     425//                 debugWarning("Could not encode port %s to Midi events",(*it)->getName().c_str()); 
     426//                 no_problem=false; 
     427//             } 
     428            break; 
    473429        default: // ignore 
    474430            break; 
     
    484440    // doesn't read from the port buffers. 
    485441    bool no_problem = true; 
    486     for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    487       it != m_PeriodPorts.end(); 
     442    for ( PortVectorIterator it = m_Ports.begin(); 
     443      it != m_Ports.end(); 
    488444      ++it ) { 
    489         //FIXME: make this into a static_cast when not DEBUG? 
    490         Port *port=dynamic_cast<Port *>(*it); 
     445        Port *port=(*it); 
    491446 
    492447        switch(port->getPortType()) { 
     
    498453            } 
    499454            break; 
    500         // midi is a packet based port, don't process 
    501         //    case MotuPortInfo::E_Midi: 
    502         //        break; 
    503  
     455        case Port::E_Midi: 
     456//             if (encodeSilencePortToMotuMidiEvents(static_cast<MotuMidiPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
     457//                 debugWarning("Could not encode port %s to Midi events",(*it)->getName().c_str()); 
     458//                 no_problem = false; 
     459//             } 
     460            break; 
    504461        default: // ignore 
    505462            break; 
     
    507464    } 
    508465    return no_problem; 
    509 } 
    510  
    511 /** 
    512  * @brief encode a packet for the packet-based ports 
    513  * 
    514  * @param data Packet data 
    515  * @param nevents number of events in data (including events of other ports & port types) 
    516  * @param dbc DataBlockCount value for this packet 
    517  * @return true if all successfull 
    518  */ 
    519 bool MotuTransmitStreamProcessor::encodePacketPorts(quadlet_t *data, unsigned int nevents, 
    520         unsigned int dbc) { 
    521     bool ok=true; 
    522     char byte; 
    523  
    524     // Use char here since the target address won't necessarily be 
    525     // aligned; use of an unaligned quadlet_t may cause issues on 
    526     // certain architectures.  Besides, the target for MIDI data going 
    527     // directly to the MOTU isn't structured in quadlets anyway; it is a 
    528     // sequence of 3 unaligned bytes. 
    529     unsigned char *target = NULL; 
    530  
    531     for ( PortVectorIterator it = m_PacketPorts.begin(); 
    532         it != m_PacketPorts.end(); 
    533         ++it ) { 
    534  
    535         Port *port=static_cast<Port *>(*it); 
    536          assert(port); // this should not fail!! 
    537  
    538         // Currently the only packet type of events for MOTU 
    539         // is MIDI in mbla.  However in future control data 
    540         // might also be sent via "packet" events. 
    541         // assert(pinfo->getFormat()==MotuPortInfo::E_Midi); 
    542  
    543         // FIXME: MIDI output is completely untested at present. 
    544         switch (port->getPortType()) { 
    545             case Port::E_Midi: { 
    546                 MotuMidiPort *mp=static_cast<MotuMidiPort *>(*it); 
    547  
    548                 // Send a byte if we can. MOTU MIDI data is 
    549                 // sent using a 3-byte sequence starting at 
    550                 // the port's position.  For now we'll 
    551                 // always send in the first event of a 
    552                 // packet, but this might need refinement 
    553                 // later. 
    554                 if (mp->canRead()) { 
    555                     mp->readEvent(&byte); 
    556                     target = (unsigned char *)data + mp->getPosition(); 
    557                     *(target++) = 0x01; 
    558                     *(target++) = 0x00; 
    559                     *(target++) = byte; 
    560                 } 
    561                 break; 
    562             } 
    563             default: 
    564                 debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown packet-type port type %d\n",port->getPortType()); 
    565                 return ok; 
    566               } 
    567     } 
    568  
    569     return ok; 
    570466} 
    571467 
  • branches/api-cleanup/src/motu/motu_avdevice.cpp

    r785 r809  
    554554    // event data. 
    555555    asprintf(&buff,"%s_cap_MIDI0",id.c_str()); 
    556     p = new Streaming::MotuMidiPort(buff, 
     556    p = new Streaming::MotuMidiPort(*m_receiveProcessor, buff, 
    557557        Streaming::Port::E_Capture, 4); 
    558558    if (!p) { 
    559559        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n", buff); 
    560     } else { 
    561         if (!m_receiveProcessor->addPort(p)) { 
    562             debugWarning("Could not register port with stream processor\n"); 
    563             free(buff); 
    564             return false; 
    565         } else { 
    566             debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n", buff); 
    567         } 
    568560    } 
    569561    free(buff); 
     
    613605    // of the event data. 
    614606    asprintf(&buff,"%s_pbk_MIDI0",id.c_str()); 
    615     p = new Streaming::MotuMidiPort(buff, 
     607    p = new Streaming::MotuMidiPort(*m_transmitProcessor, buff, 
    616608        Streaming::Port::E_Capture, 4); 
    617609    if (!p) { 
    618610        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n", buff); 
    619     } else { 
    620         if (!m_receiveProcessor->addPort(p)) { 
    621             debugWarning("Could not register port with stream processor\n"); 
    622             free(buff); 
    623             return false; 
    624         } else { 
    625             debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n", buff); 
    626         } 
    627611    } 
    628612    free(buff); 
     
    862846Streaming::Port *p=NULL; 
    863847 
    864     p = new Streaming::MotuAudioPort(name, direction, position, size); 
     848    p = new Streaming::MotuAudioPort(*s_processor, name, direction, position, size); 
    865849 
    866850    if (!p) { 
    867851        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",name); 
    868     } else { 
    869         if (!s_processor->addPort(p)) { 
    870             debugWarning("Could not register port with stream processor\n"); 
    871             free(name); 
    872             return false; 
    873         } else { 
    874             debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",name); 
    875         } 
    876         p->enable(); 
    877852    } 
    878853    free(name); 
  • branches/api-cleanup/tests/streaming/SConscript

    r792 r809  
    3030env.PrependUnique( LIBS=["ffado"] ) 
    3131 
    32 apps = "teststreaming teststreaming2" 
    33 if env.GetOption('clean') or env['ALSA_SEQ_OUTPUT']: 
    34         apps += " testmidistreaming1" 
    35  
    36 for app in env.Split( apps ): 
    37         env.Program( target=app, source = [ app+".c", "debugtools.c" ] ) 
    38  
    3932cppapps = "teststreaming3" 
    4033 
  • branches/api-cleanup/tests/streaming/teststreaming3.cpp

    r807 r809  
    321321    for (i=0; i < nb_in_channels; i++) { 
    322322        audiobuffers_in[i] = (float *)calloc(arguments.period+1, sizeof(float)); 
    323              
     323 
    324324        switch (ffado_streaming_get_capture_stream_type(dev,i)) { 
    325325            case ffado_stream_type_audio: 
     
    331331                // this is done with read/write routines because the nb of bytes can differ. 
    332332            case ffado_stream_type_midi: 
     333                // note that using a float * buffer for midievents is a HACK 
     334                ffado_streaming_set_capture_stream_buffer(dev, i, (char *)(audiobuffers_in[i])); 
     335                ffado_streaming_set_capture_buffer_type(dev, i, ffado_buffer_type_midi); 
     336                ffado_streaming_capture_stream_onoff(dev, i, 1); 
    333337            default: 
    334338                break; 
    335339        } 
    336340    } 
    337      
     341 
    338342    audiobuffers_out = (float **)calloc(nb_out_channels, sizeof(float)); 
    339343    for (i=0; i < nb_out_channels; i++) { 
    340344        audiobuffers_out[i] = (float *)calloc(arguments.period+1, sizeof(float)); 
    341              
     345 
    342346        switch (ffado_streaming_get_playback_stream_type(dev,i)) { 
    343347            case ffado_stream_type_audio: 
     
    349353                // this is done with read/write routines because the nb of bytes can differ. 
    350354            case ffado_stream_type_midi: 
     355                ffado_streaming_set_playback_buffer_type(dev, i, ffado_buffer_type_midi); 
     356                ffado_streaming_playback_stream_onoff(dev, i, 0); 
    351357            default: 
    352358                break; 
     
    413419            } 
    414420        } else { 
     421            uint32_t *midibuffer; 
     422            int idx; 
    415423            for (i=0; i < min_ch_count; i++) { 
    416424                switch (ffado_streaming_get_capture_stream_type(dev,i)) { 
     
    423431                        // this is done with read/write routines because the nb of bytes can differ. 
    424432                    case ffado_stream_type_midi: 
     433                        midibuffer=(uint32_t *)audiobuffers_in[i]; 
     434                        for(idx=0; idx < arguments.period; idx++) { 
     435                            uint32_t midievent = *(midibuffer + idx); 
     436                            if(midievent & 0xFF000000) { 
     437                                debugOutput(DEBUG_LEVEL_NORMAL, " Received midi event %08X on idx %d of period %d\n",  
     438                                            midievent, idx, nb_periods); 
     439                            } 
     440                        } 
    425441                    default: 
    426442                        break;