Changeset 227

Show
Ignore:
Timestamp:
05/27/06 14:43:40 (16 years ago)
Author:
pieterpalmers
Message:

- another day of good progress comes to and end...
- compiles and runs, only the midi stuff and the xrun handling remain.

I'll also have to rework the C API somewhat.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/libfreebob-2.0/libfreebob/freebob_streaming.h

    r225 r227  
    177177 
    178178/** 
     179 * preparation should be done after setting all per-stream parameters 
     180 * the way you want them. being buffer data type etc... 
     181 * 
     182 * @param dev the freebob device 
     183 * @return  
     184 */ 
     185bool freebob_streaming_prepare(freebob_device_t *dev); 
     186 
     187 
     188/** 
    179189 * Finishes the FreeBob streaming. Cleans up all internal data structures 
    180190 * and terminates connections. 
  • branches/libfreebob-2.0/src/bebob_light/bebob_light_avdevice.cpp

    r225 r227  
    18011801                        case ExtendedPlugInfoClusterInfoSpecificData::ePT_Analog: 
    18021802                                p=new FreebobStreaming::AmdtpAudioPort( 
    1803                                                 channelInfo->m_name,  
    1804                                                 FreebobStreaming::AmdtpAudioPort::E_Int24, // changed in the audio part 
    1805                                                 FreebobStreaming::AmdtpAudioPort::E_PeriodBuffered,  
    1806                                                 0, // changed in the audio part 
     1803                                                channelInfo->m_name, 
    18071804                                                direction,  
    18081805                                                // \todo: streaming backend expects indexing starting from 0 
     
    18171814 
    18181815                        case ExtendedPlugInfoClusterInfoSpecificData::ePT_MIDI: 
     1816                                p=new FreebobStreaming::AmdtpMidiPort( 
     1817                                                channelInfo->m_name,  
     1818                                                direction,  
     1819                                                // \todo: streaming backend expects indexing starting from 0 
     1820                                                // but bebob reports it starting from 1. Decide where 
     1821                                                // and how to handle this (pp: here) 
     1822                                                channelInfo->m_streamPosition - 1,  
     1823                                                channelInfo->m_location,  
     1824                                                FreebobStreaming::AmdtpPortInfo::E_Midi,  
     1825                                                clusterInfo->m_portType 
     1826                                ); 
     1827 
    18191828                                break; 
    18201829                        case ExtendedPlugInfoClusterInfoSpecificData::ePT_SPDIF: 
     
    18331842                        } else { 
    18341843                 
    1835                                 if (processor->addPort(p)) { 
     1844                                if (!processor->addPort(p)) { 
    18361845                                        debugWarning("Could not register port with stream processor\n"); 
    18371846                                        return false; 
  • branches/libfreebob-2.0/src/libstreaming/AmdtpPort.cpp

    r221 r227  
    3232namespace FreebobStreaming { 
    3333 
     34AmdtpMidiPort::AmdtpMidiPort(std::string name,  
     35                           enum E_Direction direction, 
     36                           int position,  
     37                           int location,  
     38                           enum E_Formats format,  
     39                           int type) 
     40        : MidiPort(name, direction), 
     41          AmdtpPortInfo(name, position, location, format, type) 
     42          , m_countdown(0) 
     43{ 
     44        m_ringbuffer=freebob_ringbuffer_create(m_buffersize * getEventSize()); 
     45         
     46        if(!m_ringbuffer) { 
     47                debugFatal("Could not allocate ringbuffer\n"); 
     48                m_buffersize=0; 
     49        } 
     50         
     51} 
     52 
     53AmdtpMidiPort::~AmdtpMidiPort() { 
     54        if (m_ringbuffer) freebob_ringbuffer_free(m_ringbuffer); 
     55         
     56} 
     57 
     58/** 
     59 * The problem with MIDI ports is that there is no guaranteed availability of data. 
     60 * This function will return true if:  
     61 *  (1) there is a byte ready in the buffer 
     62 *  (2) we are allowed to send a byte 
     63 * 
     64 * it will also assume that you actually are sending a byte, and it will reset 
     65 * the countdown 
     66 * 
     67 * note on (2): the midi over 1394 spec limits the speed of sending midi data bytes. 
     68 *              For every (time muxed) channel, you can send only one midi byte every 
     69 *              320 microseconds. The packet rate is 8000pkt/sec, or 125us. Therefore 
     70 *              we wait (at least) two packets before sending another byte. This comes 
     71 *              down to 375us, so there is a slight limiting of the bandwidth. 
     72 * 
     73 * \todo fix the too long delay (375us instead of 320us) 
     74 * 
     75 * @return true if you can send a midi byte 
     76 */ 
     77bool AmdtpMidiPort::canSend() { 
     78        bool byte_present_in_buffer; 
     79        assert(m_ringbuffer); 
     80         
     81        byte_present_in_buffer=(freebob_ringbuffer_read_space(m_ringbuffer)>=sizeof(char)); 
     82         
     83        if(byte_present_in_buffer && (m_countdown < 0)) { 
     84                m_countdown=2; 
     85                return true; 
     86        } 
     87        return false; 
     88} 
    3489 
    3590} // end of namespace FreebobStreaming 
  • branches/libfreebob-2.0/src/libstreaming/AmdtpPort.h

    r225 r227  
    5252 
    5353        AmdtpAudioPort(std::string name,  
    54                            enum E_DataType datatype, 
    55                            enum E_BufferType buffertype,  
    56                            unsigned int buffsize, 
    57                        enum E_Direction direction, 
     54                           enum E_Direction direction, 
    5855                           int position,  
    5956                           int location,  
    6057                           enum E_Formats format,  
    6158                           int type) 
    62         : AudioPort(name, datatype,     buffertype, buffsize, direction), 
    63           AmdtpPortInfo(name, position, location, format, type) 
    64         {}; 
    65  
    66         AmdtpAudioPort(std::string name,  
    67                            enum E_DataType datatype, 
    68                            enum E_BufferType buffertype,  
    69                            unsigned int buffsize, 
    70                        void *externalbuffer, 
    71                        enum E_Direction direction, 
    72                            int position,  
    73                            int location,  
    74                            enum E_Formats format,  
    75                            int type) 
    76         : AudioPort(name, datatype,     buffertype, buffsize, externalbuffer, direction), 
     59        : AudioPort(name, direction), 
    7760          AmdtpPortInfo(name, position, location, format, type) 
    7861        {}; 
     
    9780 
    9881        AmdtpMidiPort(std::string name,  
    99                            unsigned int buffsize, 
    100                        enum E_Direction direction, 
     82                           enum E_Direction direction, 
    10183                           int position,  
    10284                           int location,  
    10385                           enum E_Formats format,  
    104                            int type) 
    105         : MidiPort(name, buffsize, direction), 
    106           AmdtpPortInfo(name, position, location, format, type) 
    107         {}; 
     86                           int type); 
    10887 
    109         virtual ~AmdtpMidiPort() {}; 
     88        virtual ~AmdtpMidiPort(); 
     89         
     90        bool canSend(); ///< can we send a byte 
     91        void trigger(){m_countdown--;}; ///< call this every time a byte could have been sent 
    11092 
    11193protected: 
    112  
     94        int m_countdown; 
     95         
    11396}; 
    11497 
  • branches/libfreebob-2.0/src/libstreaming/AmdtpStreamProcessor.cpp

    r226 r227  
    129129                *length = read_size + 8; 
    130130                 
    131                 // TODO: we should do all packet buffered processing here 
    132 //              freebob_streaming_encode_midi(connection,(quadlet_t *)(data+8), nevents, packet->dbc); 
     131                // process all ports that should be handled on a per-packet base 
     132                // this is MIDI for AMDTP (due to the need of DBC) 
     133                if (!encodePacketPorts((quadlet_t *)(data+8), nevents, packet->dbc)) { 
     134                        debugWarning("Problem encoding Packet Ports\n"); 
     135                } 
    133136        } 
    134137         
     
    221224//              return -ENOMEM; 
    222225        } 
    223          
    224         // we should transfer the port buffer contents to the event buffer 
     226 
     227        // set the parameters of ports we can: 
     228        // we want the audio ports to be period buffered, 
     229        // and the midi ports to be packet buffered 
     230        for ( PortVectorIterator it = m_Ports.begin(); 
     231                  it != m_Ports.end(); 
     232                  ++it ) 
     233        { 
     234                debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str()); 
     235                if(!(*it)->setBufferSize(m_period)) { 
     236                        debugFatal("Could not set buffer size to %d\n",m_period); 
     237                        return false; 
     238                } 
     239                 
     240                 
     241                switch ((*it)->getPortType()) { 
     242                        case Port::E_Audio: 
     243                                if(!(*it)->setSignalType(Port::E_PeriodSignalled)) { 
     244                                        debugFatal("Could not set signal type to PeriodSignalling"); 
     245                                        return false; 
     246                                } 
     247                                debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n"); 
     248                                // buffertype and datatype are dependant on the API 
     249                                if(!(*it)->setBufferType(Port::E_PointerBuffer)) { 
     250                                        debugFatal("Could not set buffer type"); 
     251                                        return false; 
     252                                } 
     253                                if(!(*it)->useExternalBuffer(true)) { 
     254                                        debugFatal("Could not set external buffer usage"); 
     255                                        return false; 
     256                                } 
     257                                 
     258                                if(!(*it)->setDataType(Port::E_Float)) { 
     259                                        debugFatal("Could not set data type"); 
     260                                        return false; 
     261                                } 
     262                                 
     263                                 
     264                                break; 
     265                        case Port::E_Midi: 
     266                                if(!(*it)->setSignalType(Port::E_PacketSignalled)) { 
     267                                        debugFatal("Could not set signal type to PeriodSignalling"); 
     268                                        return false; 
     269                                } 
     270                                // buffertype and datatype are dependant on the API 
     271                                debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n"); 
     272                                // buffertype and datatype are dependant on the API 
     273                                if(!(*it)->setBufferType(Port::E_RingBuffer)) { 
     274                                        debugFatal("Could not set buffer type"); 
     275                                        return false; 
     276                                } 
     277                                if(!(*it)->setDataType(Port::E_MidiEvent)) { 
     278                                        debugFatal("Could not set data type"); 
     279                                        return false; 
     280                                } 
     281                                break; 
     282                        default: 
     283                                debugWarning("Unsupported port type specified\n"); 
     284                                break; 
     285                } 
     286        } 
     287 
     288        // the API specific settings of the ports should already be set,  
     289        // as this is called from the processorManager->prepare() 
     290        // so we can init the ports 
     291        if(!initPorts()) { 
     292                debugFatal("Could not initialize ports!\n"); 
     293                return false; 
     294        } 
     295 
     296        if(!preparePorts()) { 
     297                debugFatal("Could not initialize ports!\n"); 
     298                return false; 
     299        } 
     300 
     301        // we should prefill the event buffer 
     302        // FIXME: i have to solve this otherwise because the ports aren't ready yet 
     303        // especially if there are no internal buffers=> segfault 
    225304        int i=m_nb_buffers; 
    226305        while(i--) { 
    227                 if(!transfer()) { 
     306                if(!transferSilence()) { 
    228307                        debugFatal("Could not prefill transmit stream\n"); 
    229308                        return false; 
     
    243322} 
    244323 
     324bool AmdtpTransmitStreamProcessor::transferSilence() { 
     325        /* a naive implementation would look like this: */ 
     326         
     327        unsigned int write_size=m_period*sizeof(quadlet_t)*m_dimension; 
     328        char *dummybuffer=(char *)calloc(sizeof(quadlet_t),m_period*m_dimension); 
     329        transmitSilenceBlock(dummybuffer, m_period, 0); 
     330 
     331        if (freebob_ringbuffer_write(m_event_buffer,(char *)(dummybuffer),write_size) < write_size) { 
     332                debugWarning("Could not write to event buffer\n"); 
     333        } 
     334        return true; 
     335} 
     336 
    245337bool AmdtpTransmitStreamProcessor::transfer() { 
    246338 
     
    261353*/ 
    262354/* but we're not that naive anymore... */ 
    263         int i; 
    264355        int xrun; 
    265356        unsigned int offset=0; 
     
    378469                case AmdtpPortInfo::E_SPDIF: // still unimplemented 
    379470                        break; 
    380         /* for this processor, midi is a packet based port  
    381                 case AmdtpPortInfo::E_Midi: 
    382                         break;*/ 
    383471                default: // ignore 
    384472                        break; 
     
    388476 
    389477} 
     478 
     479int AmdtpTransmitStreamProcessor::transmitSilenceBlock(char *data,  
     480                                           unsigned int nevents, unsigned int offset) 
     481{ 
     482        int problem=0; 
     483 
     484        for ( PortVectorIterator it = m_PeriodPorts.begin(); 
     485          it != m_PeriodPorts.end(); 
     486          ++it ) 
     487    { 
     488 
     489                //FIXME: make this into a static_cast when not DEBUG? 
     490 
     491                AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it); 
     492                assert(pinfo); // this should not fail!! 
     493 
     494                switch(pinfo->getFormat()) { 
     495                case AmdtpPortInfo::E_MBLA: 
     496                        if(encodeSilencePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) { 
     497                                debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str()); 
     498                                problem=1; 
     499                        } 
     500                        break; 
     501                case AmdtpPortInfo::E_SPDIF: // still unimplemented 
     502                        break; 
     503                default: // ignore 
     504                        break; 
     505                } 
     506    } 
     507        return problem; 
     508 
     509} 
     510 
     511/** 
     512 * @brief decode 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 */ 
     519bool AmdtpTransmitStreamProcessor::encodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc) 
     520{ 
     521        bool ok=true; 
     522        char byte; 
     523         
     524        quadlet_t *target_event=NULL; 
     525        int j; 
     526         
     527        for ( PortVectorIterator it = m_PacketPorts.begin(); 
     528          it != m_PacketPorts.end(); 
     529          ++it ) 
     530        { 
     531 
     532#ifdef DEBUG 
     533                AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it); 
     534                assert(pinfo); // this should not fail!! 
     535 
     536                // the only packet type of events for AMDTP is MIDI in mbla 
     537                assert(pinfo->getFormat()==AmdtpPortInfo::E_Midi); 
     538#endif 
     539                 
     540                AmdtpMidiPort *mp=static_cast<AmdtpMidiPort *>(*it); 
     541                 
     542                // we encode this directly (no function call) due to the high frequency 
     543                /* idea: 
     544                spec says: current_midi_port=(dbc+j)%8; 
     545                => if we start at (dbc+stream->location-1)%8 [due to location_min=1],  
     546                we'll start at the right event for the midi port. 
     547                => if we increment j with 8, we stay at the right event. 
     548                */ 
     549                // FIXME: as we know in advance how big a packet is (syt_interval) we can  
     550                //        predict how much loops will be present here 
     551                // first prefill the buffer with NO_DATA's on all time muxed channels 
     552                 
     553                for(j = (dbc & 0x07)+mp->getLocation()-1; j < nevents; j += 8) { 
     554                 
     555                        target_event=(quadlet_t *)(data + ((j * m_dimension) + mp->getPosition())); 
     556                         
     557                        if(mp->canSend()) { // we can send a byte 
     558                                mp->readEvent(&byte); 
     559                                *target_event=htonl( 
     560                                        IEC61883_AM824_SET_LABEL((byte)<<16, 
     561                                                                 IEC61883_AM824_LABEL_MIDI_1X)); 
     562                        } else {  
     563                                // can't send a byte, either because there is no byte, 
     564                                // or because this would exceed the maximum rate 
     565                                *target_event=htonl( 
     566                                        IEC61883_AM824_SET_LABEL(0,IEC61883_AM824_LABEL_MIDI_NO_DATA)); 
     567                        } 
     568                        mp->trigger(); 
     569                } 
     570 
     571        } 
     572         
     573        return ok; 
     574} 
     575 
    390576 
    391577int AmdtpTransmitStreamProcessor::encodePortToMBLAEvents(AmdtpAudioPort *p, quadlet_t *data,  
     
    440626        return 0; 
    441627} 
     628int AmdtpTransmitStreamProcessor::encodeSilencePortToMBLAEvents(AmdtpAudioPort *p, quadlet_t *data,  
     629                                           unsigned int offset, unsigned int nevents) 
     630{ 
     631        unsigned int j=0; 
     632 
     633        quadlet_t *target_event; 
     634 
     635        target_event=(quadlet_t *)(data + p->getPosition()); 
     636 
     637        switch(p->getDataType()) { 
     638                default: 
     639                case Port::E_Int24: 
     640                case Port::E_Float: 
     641                        { 
     642                                for(j = 0; j < nevents; j += 1) { // decode max nsamples 
     643                                        *target_event = htonl(0x40000000); 
     644                                        target_event += m_dimension; 
     645                                } 
     646                        } 
     647                        break; 
     648        } 
     649 
     650        return 0; 
     651} 
    442652 
    443653/* --------------------- RECEIVE ----------------------- */ 
     
    456666 
    457667bool AmdtpReceiveStreamProcessor::init() { 
    458         int err=0; 
    459          
    460          
    461668        // call the parent init 
    462669        // this has to be done before allocating the buffers,  
     
    502709                } else { 
    503710                        retval=RAW1394_ISO_OK; 
    504                         // we cannot offload midi encoding due to the need for a dbc value 
    505 //                      freebob_streaming_decode_midi(connection,(quadlet_t *)(data+8), nevents, packet->dbc); 
     711                        // process all ports that should be handled on a per-packet base 
     712                        // this is MIDI for AMDTP (due to the need of DBC) 
     713                        if (!decodePacketPorts((quadlet_t *)(data+8), nevents, packet->dbc)) { 
     714                                debugWarning("Problem decoding Packet Ports\n"); 
     715                        } 
    506716                } 
    507717 
     
    596806        } 
    597807 
    598  
    599          
     808        // set the parameters of ports we can: 
     809        // we want the audio ports to be period buffered, 
     810        // and the midi ports to be packet buffered 
     811        for ( PortVectorIterator it = m_Ports.begin(); 
     812                  it != m_Ports.end(); 
     813                  ++it ) 
     814        { 
     815                debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str()); 
     816                if(!(*it)->setBufferSize(m_period)) { 
     817                        debugFatal("Could not set buffer size to %d\n",m_period); 
     818                        return false; 
     819                } 
     820 
     821                switch ((*it)->getPortType()) { 
     822                        case Port::E_Audio: 
     823                                if(!(*it)->setSignalType(Port::E_PeriodSignalled)) { 
     824                                        debugFatal("Could not set signal type to PeriodSignalling"); 
     825                                        return false; 
     826                                } 
     827                                // buffertype and datatype are dependant on the API 
     828                                debugWarning("---------------- ! Doing hardcoded dummy setup ! --------------\n"); 
     829                                // buffertype and datatype are dependant on the API 
     830                                if(!(*it)->setBufferType(Port::E_PointerBuffer)) { 
     831                                        debugFatal("Could not set buffer type"); 
     832                                        return false; 
     833                                } 
     834                                if(!(*it)->useExternalBuffer(true)) { 
     835                                        debugFatal("Could not set external buffer usage"); 
     836                                        return false; 
     837                                } 
     838                                if(!(*it)->setDataType(Port::E_Float)) { 
     839                                        debugFatal("Could not set data type"); 
     840                                        return false; 
     841                                } 
     842                                break; 
     843                        case Port::E_Midi: 
     844                                if(!(*it)->setSignalType(Port::E_PacketSignalled)) { 
     845                                        debugFatal("Could not set signal type to PacketSignalling"); 
     846                                        return false; 
     847                                } 
     848                                // buffertype and datatype are dependant on the API 
     849                                // buffertype and datatype are dependant on the API 
     850                                debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n"); 
     851                                // buffertype and datatype are dependant on the API 
     852                                if(!(*it)->setBufferType(Port::E_RingBuffer)) { 
     853                                        debugFatal("Could not set buffer type"); 
     854                                        return false; 
     855                                } 
     856                                if(!(*it)->setDataType(Port::E_MidiEvent)) { 
     857                                        debugFatal("Could not set data type"); 
     858                                        return false; 
     859                                } 
     860                                break; 
     861                        default: 
     862                                debugWarning("Unsupported port type specified\n"); 
     863                                break; 
     864                } 
     865 
     866        } 
     867 
     868        // the API specific settings of the ports should already be set,  
     869        // as this is called from the processorManager->prepare() 
     870        // so we can init the ports 
     871        if(!initPorts()) { 
     872                debugFatal("Could not initialize ports!\n"); 
     873                return false; 
     874        } 
     875 
     876        if(!preparePorts()) { 
     877                debugFatal("Could not initialize ports!\n"); 
     878                return false; 
     879        } 
     880 
     881 
    600882        debugOutput( DEBUG_LEVEL_VERBOSE, "Prepared for:\n"); 
    601883        debugOutput( DEBUG_LEVEL_VERBOSE, " Samplerate: %d, DBS: %d, SYT: %d\n", 
     
    624906        free(dummybuffer); 
    625907*/ 
    626         int i; 
    627908        int xrun; 
    628909        unsigned int offset=0; 
     
    699980                } 
    700981                         
    701                        // the bytes2read should always be cluster aligned 
     982                // the bytes2read should always be cluster aligned 
    702983                assert(bytes2read%cluster_size==0); 
    703984        } 
     
    706987} 
    707988 
    708 /*  
    709  * write received events to the stream ringbuffers. 
     989/** 
     990 * \brief write received events to the stream ringbuffers. 
    710991 */ 
    711  
    712992int AmdtpReceiveStreamProcessor::receiveBlock(char *data,  
    713993                                           unsigned int nevents, unsigned int offset) 
     
    7451025} 
    7461026 
     1027/** 
     1028 * @brief decode a packet for the packet-based ports 
     1029 * 
     1030 * @param data Packet data 
     1031 * @param nevents number of events in data (including events of other ports & port types) 
     1032 * @param dbc DataBlockCount value for this packet 
     1033 * @return true if all successfull 
     1034 */ 
     1035bool AmdtpReceiveStreamProcessor::decodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc) 
     1036{ 
     1037        bool ok=true; 
     1038         
     1039        quadlet_t *target_event=NULL; 
     1040        int j; 
     1041         
     1042        for ( PortVectorIterator it = m_PacketPorts.begin(); 
     1043          it != m_PacketPorts.end(); 
     1044          ++it ) 
     1045        { 
     1046 
     1047#ifdef DEBUG 
     1048                AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it); 
     1049                assert(pinfo); // this should not fail!! 
     1050 
     1051                // the only packet type of events for AMDTP is MIDI in mbla 
     1052                assert(pinfo->getFormat()==AmdtpPortInfo::E_Midi); 
     1053#endif 
     1054                AmdtpMidiPort *mp=static_cast<AmdtpMidiPort *>(*it); 
     1055                 
     1056                // we decode this directly (no function call) due to the high frequency 
     1057                /* idea: 
     1058                spec says: current_midi_port=(dbc+j)%8; 
     1059                => if we start at (dbc+stream->location-1)%8 [due to location_min=1],  
     1060                we'll start at the right event for the midi port. 
     1061                => if we increment j with 8, we stay at the right event. 
     1062                */ 
     1063                // FIXME: as we know in advance how big a packet is (syt_interval) we can  
     1064                //        predict how much loops will be present here 
     1065                for(j = (dbc & 0x07)+mp->getLocation()-1; j < nevents; j += 8) { 
     1066                        target_event=(quadlet_t *)(data + ((j * m_dimension) + mp->getPosition())); 
     1067                        quadlet_t sample_int=ntohl(*target_event); 
     1068                        if(IEC61883_AM824_GET_LABEL(sample_int) != IEC61883_AM824_LABEL_MIDI_NO_DATA) { 
     1069                                sample_int=(sample_int >> 16) & 0xFF; 
     1070                                if(!mp->writeEvent(&sample_int)) { 
     1071                                        debugWarning("Packet port events lost\n"); 
     1072                                        ok=false; 
     1073                                } 
     1074                        } 
     1075                } 
     1076 
     1077        } 
     1078         
     1079        return ok; 
     1080} 
     1081 
    7471082int AmdtpReceiveStreamProcessor::decodeMBLAEventsToPort(AmdtpAudioPort *p, quadlet_t *data,  
    7481083                                           unsigned int offset, unsigned int nevents) 
  • branches/libfreebob-2.0/src/libstreaming/AmdtpStreamProcessor.h

    r226 r227  
    3939#include "ringbuffer.h" 
    4040 
     41#define AMDTP_MAX_PACKET_SIZE 2048 
     42 
     43#define IEC61883_STREAM_TYPE_MIDI   0x0D 
     44#define IEC61883_STREAM_TYPE_SPDIF  0x00 
     45#define IEC61883_STREAM_TYPE_MBLA   0x06 
     46 
     47#define IEC61883_AM824_LABEL_MASK                       0xFF000000 
     48#define IEC61883_AM824_GET_LABEL(x)             (((x) & 0xFF000000) >> 24) 
     49#define IEC61883_AM824_SET_LABEL(x,y)           ((x) | ((y)<<24)) 
     50 
     51#define IEC61883_AM824_LABEL_MIDI_NO_DATA       0x80  
     52#define IEC61883_AM824_LABEL_MIDI_1X            0x81  
     53#define IEC61883_AM824_LABEL_MIDI_2X            0x82 
     54#define IEC61883_AM824_LABEL_MIDI_3X            0x83 
     55 
    4156namespace FreebobStreaming { 
    4257 
     
    7186        bool prepare(); 
    7287        bool transfer(); 
     88        bool transferSilence(); 
    7389        virtual void setVerboseLevel(int l); 
    7490 
     
    90106        int transmitBlock(char *data, unsigned int nevents,  
    91107                          unsigned int offset); 
     108                           
     109        bool encodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc); 
    92110        int encodePortToMBLAEvents(AmdtpAudioPort *, quadlet_t *data, 
     111                                   unsigned int offset, unsigned int nevents); 
     112         
     113        int transmitSilenceBlock(char *data, unsigned int nevents,  
     114                          unsigned int offset); 
     115        int encodeSilencePortToMBLAEvents(AmdtpAudioPort *, quadlet_t *data, 
    93116                                   unsigned int offset, unsigned int nevents); 
    94117 
     
    132155 
    133156        int receiveBlock(char *data, unsigned int nevents, unsigned int offset); 
     157        bool decodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc); 
     158         
    134159        int decodeMBLAEventsToPort(AmdtpAudioPort *, quadlet_t *data, unsigned int offset, unsigned int nevents); 
    135160 
  • branches/libfreebob-2.0/src/libstreaming/freebob_streaming.cpp

    r225 r227  
    6565        DeviceManager * m_deviceManager; 
    6666        StreamProcessorManager *processorManager; 
    67         StreamRunner *runner; 
    68         FreebobPosixThread *thread; 
    6967 
    7068        freebob_options_t options; 
     
    9997        } 
    10098 
    101  
    102         // also create a processor manager to manage the actual stream 
     99        // create a processor manager to manage the actual stream 
    103100        // processors    
    104101        dev->processorManager = new StreamProcessorManager(dev->options.period_size,dev->options.nb_buffers); 
     
    109106                return 0; 
    110107        } 
     108         
    111109        dev->processorManager->setVerboseLevel(DEBUG_LEVEL_VERBOSE); 
    112110        if(!dev->processorManager->init()) { 
     
    118116        } 
    119117 
    120         // now create the runner that does the actual streaming 
    121         dev->runner = new StreamRunner(dev->processorManager); 
    122         if(!dev->runner) { 
    123                 debugFatal("Could not create StreamRunner\n"); 
    124                 delete dev->processorManager; 
    125                 delete dev->m_deviceManager; 
    126                 delete dev; 
    127                 return 0; 
    128         } 
    129  
    130         // and the tread that runs the runner 
    131         dev->thread=new FreebobPosixThread(dev->runner); 
    132         if(!dev->thread) { 
    133                 debugFatal("Could not create Thread for streamrunner\n"); 
    134                 delete dev->runner; 
    135                 delete dev->processorManager; 
    136                 delete dev->m_deviceManager; 
    137                 delete dev; 
    138                 return 0; 
    139         } 
    140  
    141         dev->runner->setVerboseLevel(DEBUG_LEVEL_VERBOSE); 
    142         dev->processorManager->setVerboseLevel(DEBUG_LEVEL_VERBOSE); 
    143  
    144118        // discover the devices on the bus 
    145119        if(!dev->m_deviceManager->discover(DEBUG_LEVEL_NORMAL)) { 
     
    169143 
    170144        // we are ready! 
     145        freebob_streaming_prepare(dev); 
    171146 
    172147        debugOutputShort(DEBUG_LEVEL_VERBOSE, "\n\n"); 
     
    175150} 
    176151 
     152/** 
     153 * preparation should be done after setting all per-stream parameters 
     154 * the way you want them. being buffer data type etc... 
     155 * 
     156 * @param dev  
     157 * @return  
     158 */ 
     159bool freebob_streaming_prepare(freebob_device_t *dev) { 
     160        int i=0; 
     161         
     162        dev->processorManager->prepare(); 
     163 
     164        return true; 
     165} 
     166 
    177167void freebob_streaming_finish(freebob_device_t *dev) { 
    178168 
    179169        assert(dev); 
    180170 
    181         delete dev->thread; 
    182         delete dev->runner; 
    183171        delete dev->processorManager; 
    184172        delete dev->m_deviceManager; 
     
    209197        } 
    210198 
    211          
    212         dev->processorManager->prepare(); 
    213          
    214         // start the runner thread 
    215         dev->thread->Start(); 
    216          
    217199        dev->processorManager->start(); 
    218200 
    219         int cycle=0; 
    220 //      if(dev->isoManager->startHandlers(cycle)) { 
    221 //              debugFatal("Could not start handlers\n"); 
    222 //              return -1; 
    223 //      } 
    224201        return 0; 
    225202} 
     
    229206        debugOutput(DEBUG_LEVEL_VERBOSE,"------------- Stop -------------\n"); 
    230207 
    231         dev->thread->Stop(); 
    232  
    233 //      dev->isoManager->stopHandlers(); 
    234208        dev->processorManager->stop(); 
    235209 
     
    240214                IAvDevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); 
    241215                assert(device); 
     216                 
     217                debugOutput(DEBUG_LEVEL_VERBOSE,"Stopping stream %d\n",i); 
    242218 
    243219                int j=0; 
     
    284260                        dev->processorManager->dumpInfo(); 
    285261                        debugOutput(DEBUG_LEVEL_VERBOSE, "--------------------------------------------\n"); 
    286                         hexDumpQuadlets((quadlet_t*)(dev->processorManager->getPortByIndex(0, Port::E_Capture)->getBufferAddress()),10); 
     262                        quadlet_t *addr=(quadlet_t*)(dev->processorManager->getPortByIndex(0, Port::E_Capture)->getBufferAddress()); 
     263                        if (addr) hexDumpQuadlets(addr,10); 
    287264                        debugOutput(DEBUG_LEVEL_VERBOSE, "============================================\n"); 
    288265                        debugOutput(DEBUG_LEVEL_VERBOSE, "\n"); 
     
    307284 
    308285int freebob_streaming_write(freebob_device_t *dev, int i, freebob_sample_t *buffer, int nsamples) { 
    309         return 0; 
     286//      debugFatal("Not implemented\n"); 
     287        Port *p=dev->processorManager->getPortByIndex(i, Port::E_Playback); 
     288        // use an assert here performancewise,  
     289        // it should already have failed before, if not correct 
     290        assert(p);  
     291         
     292        return p->writeEvents((void *)buffer, nsamples); 
    310293} 
    311294 
    312295int freebob_streaming_read(freebob_device_t *dev, int i, freebob_sample_t *buffer, int nsamples) { 
    313         return 0; 
     296        Port *p=dev->processorManager->getPortByIndex(i, Port::E_Capture); 
     297        // use an assert here performancewise,  
     298        // it should already have failed before, if not correct 
     299        assert(p);  
     300         
     301        return p->readEvents((void *)buffer, nsamples); 
    314302} 
    315303 
    316304pthread_t freebob_streaming_get_packetizer_thread(freebob_device_t *dev) { 
     305//      debugFatal("Not implemented\n"); 
    317306        return 0; 
    318307} 
     
    394383int freebob_streaming_set_capture_stream_buffer(freebob_device_t *dev, int i, char *buff,  freebob_streaming_buffer_type t) { 
    395384        Port *p=dev->processorManager->getPortByIndex(i, Port::E_Capture); 
    396         if(!p) { 
    397                 debugWarning("Could not get playback port at index %d\n",i); 
    398                 return -1; 
    399         } 
    400         switch(t) { 
    401         case freebob_buffer_type_uint24: 
    402                 p->setDataType(Port::E_Int24); 
    403                 p->setBufferAddress((void *)buff); 
    404                 return 0; 
    405 //              break; 
    406         case freebob_buffer_type_float: 
    407                 p->setDataType(Port::E_Float); 
    408                 p->setBufferAddress((void *)buff); 
    409                 return 0; 
    410         case freebob_buffer_type_per_stream: 
    411                 p->setDataType(Port::E_Int24); 
    412 //              p->detachBuffer(); 
    413  
    414                 break; 
    415         } 
     385         
     386        // use an assert here performancewise,  
     387        // it should already have failed before, if not correct 
     388        assert(p);  
     389         
     390        p->setExternalBufferAddress((void *)buff); 
    416391 
    417392        return 0; 
     
    421396int freebob_streaming_set_playback_stream_buffer(freebob_device_t *dev, int i, char *buff,  freebob_streaming_buffer_type t) { 
    422397        Port *p=dev->processorManager->getPortByIndex(i, Port::E_Playback); 
    423         if(!p) { 
    424                 debugWarning("Could not get playback port at index %d\n",i); 
    425                 return -1; 
    426         } 
    427         switch(t) { 
    428         case freebob_buffer_type_uint24: 
    429                 p->setDataType(Port::E_Int24); 
    430                 p->setBufferAddress((void *)buff); 
    431                 return 0; 
    432         case freebob_buffer_type_float: 
    433                 p->setDataType(Port::E_Float); 
    434                 p->setBufferAddress((void *)buff); 
    435                 return 0; 
    436         case freebob_buffer_type_per_stream: 
    437                 p->setDataType(Port::E_Int24); 
    438 //              p->detachBuffer(); 
    439  
    440                 break; 
    441         } 
    442  
    443         return 0; 
    444 
    445  
     398        // use an assert here performancewise,  
     399        // it should already have failed before, if not correct 
     400        assert(p);  
     401         
     402        p->setExternalBufferAddress((void *)buff); 
     403 
     404        return 0; 
     405
     406 
  • branches/libfreebob-2.0/src/libstreaming/Port.cpp

    r225 r227  
    3636IMPL_DEBUG_MODULE( Port, Port, DEBUG_LEVEL_NORMAL ); 
    3737 
    38 Port::Port(std::string name, enum E_BufferType type, unsigned int buffsize,  
    39            enum E_DataType datatype, enum E_PortType porttype, enum E_Direction direction)  
    40   : m_Name(name), 
    41     m_BufferType(type), 
    42     m_enabled(true), 
    43     m_buffersize(buffsize), 
    44         m_datatype(datatype), 
    45         m_porttype(porttype), 
    46         m_direction(direction), 
     38Port::Port(std::string name, enum E_PortType porttype, enum E_Direction direction)  
     39        : m_Name(name), 
     40        m_SignalType(E_PeriodSignalled), 
     41        m_BufferType(E_PointerBuffer), 
     42        m_enabled(true), 
     43        m_buffersize(0), 
     44        m_eventsize(0), 
     45        m_DataType(E_Int24), 
     46        m_PortType(porttype), 
     47        m_Direction(direction), 
    4748        m_buffer(0), 
    48     m_buffer_attached(false) 
     49        m_ringbuffer(0), 
     50        m_use_external_buffer(false) 
    4951{ 
    5052 
    51         allocateInternalBuffer(); 
    52 
    53  
    54 Port::Port(std::string name, enum E_BufferType type, unsigned int buffsize, 
    55            enum E_DataType datatype, void* externalbuffer, enum E_PortType porttype,  
    56            enum E_Direction direction)  
    57   : m_Name(name), 
    58     m_BufferType(type), 
    59     m_enabled(true), 
    60     m_buffersize(buffsize), 
    61         m_datatype(datatype), 
    62         m_porttype(porttype), 
    63         m_direction(direction), 
    64         m_buffer(externalbuffer), 
    65     m_buffer_attached(true) 
    66 
    67          
    68 
    69  
    70 // int Port::attachBuffer(void *buff) { 
    71 //  
    72 // //   if(m_buffer_attached) { 
    73 // //           debugFatal("already has a buffer attached\n"); 
    74 // //           return -1; 
    75 // //   } 
    76 // //  
    77 // //   freeInternalBuffer(); 
    78 //  
    79 //      m_buffer=buff; 
    80 //  
    81 //      m_buffer_attached=true; 
    82 //  
    83 // } 
    84  
    85 // // detach the user buffer, allocates an internal buffer 
    86 // int Port::detachBuffer() { 
    87 //      if(!m_buffer_attached) { 
    88 //              debugWarning("does not have a buffer attached\n"); 
    89 //              if(m_buffer) { 
    90 //                      return 0;        
    91 //              } // if no buffer present, there should be one allocated 
    92 //      } 
    93 //  
    94 //      m_buffer_attached=false; 
    95 //  
    96 //      return allocateInternalBuffer(); 
    97 //  
    98 // } 
     53
     54 
     55/** 
     56 * The idea is that you set all port parameters, and then initialize the port. 
     57 * This allocates all resources and makes the port usable. However, you can't 
     58 * change the port properties anymore after this. 
     59 * 
     60 * @return true if successfull. false if not (all resources are freed). 
     61 */ 
     62bool Port::init() { 
     63        if (m_initialized) { 
     64                debugFatal("Port already initialized... (%s)\n",m_Name.c_str()); 
     65                return false; 
     66        }        
     67         
     68        if (m_buffersize==0) { 
     69                debugFatal("Cannot initialize a port with buffersize=0\n"); 
     70                return false;    
     71        } 
     72         
     73        switch (m_BufferType) { 
     74                case E_PointerBuffer: 
     75                        if (m_use_external_buffer) { 
     76                                // don't do anything 
     77                        } else if (!allocateInternalBuffer()) { 
     78                                debugFatal("Could not allocate internal buffer!\n"); 
     79                                return false; 
     80                        } 
     81                        break; 
     82                         
     83                case E_RingBuffer: 
     84                        if (m_use_external_buffer) { 
     85                                debugFatal("Cannot use an external ringbuffer! \n"); 
     86                                return false; 
     87                        } else if (!allocateInternalRingBuffer()) { 
     88                                debugFatal("Could not allocate internal ringbuffer!\n"); 
     89                                return false; 
     90                        } 
     91                        break; 
     92                default: 
     93                        debugFatal("Unsupported buffer type! (%d)\n",(int)m_BufferType); 
     94                        return false; 
     95                        break; 
     96        } 
     97 
     98        m_initialized=true; 
     99         
     100        m_eventsize=getEventSize(); // this won't change, so cache it 
     101         
     102        return m_initialized; 
     103
    99104 
    100105void Port::setVerboseLevel(int l) { 
     
    102107} 
    103108 
    104 bool Port::setDataType(enum E_DataType datatype) { 
    105  
    106         m_datatype=datatype; 
    107         return eventSizeChanged(); 
    108  
     109bool Port::setName(std::string name) { 
     110        debugOutput( DEBUG_LEVEL_VERBOSE, "Setting name to %s for port %s\n",name.c_str(),m_Name.c_str()); 
     111         
     112        if (m_initialized) { 
     113                debugFatal("Port already initialized... (%s)\n",m_Name.c_str()); 
     114                return false; 
     115        } 
     116         
     117        m_Name=name; 
     118         
     119        return true; 
    109120} 
    110121 
    111122bool Port::setBufferSize(unsigned int newsize) { 
    112123        debugOutput( DEBUG_LEVEL_VERBOSE, "Setting buffersize to %d for port %s\n",newsize,m_Name.c_str()); 
     124        if (m_initialized) { 
     125                debugFatal("Port already initialized... (%s)\n",m_Name.c_str()); 
     126                return false; 
     127        } 
    113128 
    114129        m_buffersize=newsize; 
    115130        return true; 
    116          
    117 //      if(m_buffer_attached) { 
    118 //              return true; 
    119 //      } 
    120  
    121 //      freeInternalBuffer(); 
    122  
    123 //      return allocateInternalBuffer(); 
    124  
    125 
    126  
     131 
     132
     133 
     134unsigned int Port::getEventSize() { 
     135        switch (m_DataType) { 
     136                case E_Float: 
     137                        return sizeof(float); 
     138                case E_Int24: // 24 bit 2's complement, packed in a 32bit integer (LSB's) 
     139                        return sizeof(uint32_t); 
     140                case E_MidiEvent: 
     141                        return sizeof(uint32_t); 
     142                default: 
     143                        return 0; 
     144        } 
     145
     146 
     147bool Port::setDataType(enum E_DataType d) { 
     148        debugOutput( DEBUG_LEVEL_VERBOSE, "Setting datatype to %d for port %s\n",(int) d,m_Name.c_str()); 
     149        if (m_initialized) { 
     150                debugFatal("Port already initialized... (%s)\n",m_Name.c_str()); 
     151                return false; 
     152        } 
     153         
     154        // do some sanity checks 
     155        bool type_is_ok=false; 
     156        switch (m_PortType) { 
     157                case E_Audio: 
     158                        if(d == E_Int24) type_is_ok=true; 
     159                        if(d == E_Float) type_is_ok=true; 
     160                        break; 
     161                case E_Midi: 
     162                        if(d == E_MidiEvent) type_is_ok=true; 
     163                        break; 
     164                case E_Control: 
     165                        if(d == E_Default) type_is_ok=true; 
     166                        break; 
     167                default: 
     168                        break; 
     169        } 
     170         
     171        if(!type_is_ok) { 
     172                debugFatal("Datatype not supported by this type of port!\n"); 
     173                return false; 
     174        } 
     175         
     176        m_DataType=d; 
     177        return true; 
     178
     179 
     180bool Port::setSignalType(enum E_SignalType s) { 
     181        debugOutput( DEBUG_LEVEL_VERBOSE, "Setting signaltype to %d for port %s\n",(int)s,m_Name.c_str()); 
     182        if (m_initialized) { 
     183                debugFatal("Port already initialized... (%s)\n",m_Name.c_str()); 
     184                return false; 
     185        } 
     186         
     187        // do some sanity checks 
     188        bool type_is_ok=false; 
     189        switch (m_PortType) { 
     190                case E_Audio: 
     191                        if(s == E_PeriodSignalled) type_is_ok=true; 
     192                        break; 
     193                case E_Midi: 
     194                        if(s == E_PacketSignalled) type_is_ok=true; 
     195                        break; 
     196                case E_Control: 
     197                        if(s == E_PeriodSignalled) type_is_ok=true; 
     198                        break; 
     199                default: 
     200                        break; 
     201        } 
     202         
     203        if(!type_is_ok) { 
     204                debugFatal("Signalling type not supported by this type of port!\n"); 
     205                return false; 
     206        } 
     207         
     208        m_SignalType=s; 
     209        return true; 
     210 
     211
     212 
     213bool Port::setBufferType(enum E_BufferType b) { 
     214        debugOutput( DEBUG_LEVEL_VERBOSE, "Setting buffer type to %d for port %s\n",(int)b,m_Name.c_str()); 
     215        if (m_initialized) { 
     216                debugFatal("Port already initialized... (%s)\n",m_Name.c_str()); 
     217                return false; 
     218        } 
     219         
     220        // do some sanity checks 
     221        bool type_is_ok=false; 
     222        switch (m_PortType) { 
     223                case E_Audio: 
     224                        if(b == E_PointerBuffer) type_is_ok=true; 
     225                        break; 
     226                case E_Midi: 
     227                        if(b == E_RingBuffer) type_is_ok=true; 
     228                        break; 
     229                case E_Control: 
     230                        break; 
     231                default: 
     232                        break; 
     233        } 
     234         
     235        if(!type_is_ok) { 
     236                debugFatal("Buffer type not supported by this type of port!\n"); 
     237                return false; 
     238        } 
     239         
     240        m_BufferType=b; 
     241        return true; 
     242 
     243
     244 
     245bool Port::useExternalBuffer(bool b) { 
     246         
     247        debugOutput( DEBUG_LEVEL_VERBOSE, "Setting external buffer use to %d for port %s\n",(int)b,m_Name.c_str()); 
     248         
     249        if (m_initialized) { 
     250                debugFatal("Port already initialized... (%s)\n",m_Name.c_str()); 
     251                return false; 
     252        } 
     253 
     254        m_use_external_buffer=b; 
     255        return true; 
     256
     257 
     258// buffer handling api's for pointer buffers 
     259/** 
     260 * Get the buffer address (being the external or the internal one). 
     261 * 
     262 * @param buff  
     263 */ 
     264void *Port::getBufferAddress() { 
     265        assert(m_BufferType==E_PointerBuffer); 
     266        return m_buffer; 
     267}; 
     268 
     269/** 
     270 * Set the external buffer address. 
     271 * only call this when specifying an external buffer before init() 
     272 * 
     273 * @param buff  
     274 */ 
     275void Port::setExternalBufferAddress(void *buff) { 
     276        assert(m_BufferType==E_PointerBuffer); 
     277        assert(m_use_external_buffer); // don't call this with an internal buffer! 
     278        m_buffer=buff; 
     279}; 
     280 
     281// buffer handling api's for ringbuffers 
     282bool Port::writeEvent(void *event) { 
     283        assert(m_BufferType==E_RingBuffer); 
     284        assert(m_ringbuffer); 
     285         
     286        char *byte=(char *)event; 
     287        debugOutput( DEBUG_LEVEL_VERBOSE, "Writing event %02X to port %s\n",(*byte)&0xFF,m_Name.c_str()); 
     288         
     289        return (freebob_ringbuffer_write(m_ringbuffer, byte, m_eventsize)==m_eventsize); 
     290
     291 
     292bool Port::readEvent(void *event) { 
     293        assert(m_ringbuffer); 
     294         
     295        char *byte=(char *)event; 
     296        unsigned int read=freebob_ringbuffer_read(m_ringbuffer, byte, m_eventsize); 
     297         
     298        debugOutput( DEBUG_LEVEL_VERBOSE, "Reading event %X from port %s\n",(*byte),m_Name.c_str()); 
     299        return (read==m_eventsize); 
     300
     301 
     302int Port::writeEvents(void *event, unsigned int nevents) { 
     303        assert(m_BufferType==E_RingBuffer); 
     304        assert(m_ringbuffer); 
     305         
     306        char *byte=(char *)event; 
     307        unsigned int bytes2write=m_eventsize*nevents; 
     308         
     309        return (freebob_ringbuffer_write(m_ringbuffer, byte,bytes2write)/m_eventsize); 
     310 
     311
     312 
     313int Port::readEvents(void *event, unsigned int nevents) { 
     314        assert(m_ringbuffer); 
     315        char *byte=(char *)event; 
     316         
     317        unsigned int bytes2read=m_eventsize*nevents; 
     318         
     319        freebob_ringbuffer_read(m_ringbuffer, byte, bytes2read); 
     320        debugOutput( DEBUG_LEVEL_VERBOSE, "Reading events (%X) from port %s\n",(*byte),m_Name.c_str()); 
     321         
     322        return freebob_ringbuffer_read(m_ringbuffer, byte, bytes2read)/m_eventsize; 
     323
     324 
     325 
     326/* Private functions */ 
    127327 
    128328bool Port::allocateInternalBuffer() { 
    129329        int event_size=getEventSize(); 
    130  
    131         if(m_buffer_attached) { 
    132                 debugWarning("has an external buffer attached, not allocating\n"); 
    133                 return false; 
    134         } 
     330         
     331        debugOutput(DEBUG_LEVEL_VERBOSE, 
     332                    "Allocating internal buffer of %d events with size %d (%s)\n", 
     333                    m_buffersize, event_size, m_Name.c_str()); 
    135334 
    136335        if(m_buffer) { 
     
    150349 
    151350void Port::freeInternalBuffer() { 
    152         if(m_buffer_attached) { 
    153                 debugWarning("has an external buffer attached, not free-ing\n"); 
    154                 return; 
    155         } 
     351        debugOutput(DEBUG_LEVEL_VERBOSE, 
     352                    "Freeing internal buffer (%s)\n",m_Name.c_str()); 
     353 
    156354        if(m_buffer) { 
    157355                free(m_buffer); 
     
    160358} 
    161359 
    162 unsigned int Port::getEventSize() { 
    163         switch (m_datatype) { 
    164                 case E_Float: 
    165                         return sizeof(float); 
    166                 case E_Int24: // 24 bit 2's complement, packed in a 32bit integer (LSB's) 
    167                         return sizeof(uint32_t); 
    168                 case E_Byte: 
    169                         return sizeof(char); 
    170                 default: 
    171                         return 0; 
    172         } 
    173 
    174  
    175 /** 
    176  * this function should update the buffers if the event size changes 
    177  * 
    178  * \return true if there was no error 
    179  */ 
    180 bool Port::eventSizeChanged() { 
    181 //      if(m_buffer_attached) { 
    182 //              return true; // nothing to do, external buffer should be ok 
    183 //      } 
    184 //  
    185 //      freeInternalBuffer(); 
    186 //  
    187 //      return allocateInternalBuffer(); 
    188         return true; 
    189          
    190  
    191 
    192  
    193 
     360bool Port::allocateInternalRingBuffer() { 
     361        int event_size=getEventSize(); 
     362         
     363        debugOutput(DEBUG_LEVEL_VERBOSE, 
     364                    "Allocating internal buffer of %d events with size %d (%s)\n", 
     365                    m_buffersize, event_size, m_Name.c_str()); 
     366 
     367        if(m_ringbuffer) { 
     368                debugWarning("already has an internal ringbuffer attached, re-allocating\n"); 
     369                freeInternalRingBuffer(); 
     370        } 
     371 
     372        m_ringbuffer=freebob_ringbuffer_create(m_buffersize * event_size); 
     373        if (!m_ringbuffer) { 
     374                debugFatal("could not allocate internal ringbuffer\n"); 
     375                m_buffersize=0; 
     376                return false; 
     377        } 
     378 
     379        return true; 
     380
     381 
     382void Port::freeInternalRingBuffer() { 
     383        debugOutput(DEBUG_LEVEL_VERBOSE, 
     384                    "Freeing internal ringbuffer (%s)\n",m_Name.c_str()); 
     385 
     386        if(m_ringbuffer) { 
     387                freebob_ringbuffer_free(m_ringbuffer); 
     388                m_ringbuffer=0; 
     389        } 
     390
     391 
     392
  • branches/libfreebob-2.0/src/libstreaming/Port.h

    r225 r227  
    3131#include "../debugmodule/debugmodule.h" 
    3232#include <string> 
     33#include "ringbuffer.h" 
    3334 
    3435namespace FreebobStreaming { 
     
    4041 layer and the datatype-specific layer. You can define plug types by subclassing 
    4142 the base port type. 
     43  
     44 After creating a port, you have to set its parameters and then call the init() function. 
     45 This is because a port needs information from two sources to operate:  
     46 1) the stream composition information from the AvDevice 
     47 2) the streaming API setup (buffer type, data type, ...) 
     48  
     49 \note There are not much virtual functions here because of the high frequency of 
     50       calling. We try to do everything with a base class getter, and a child class 
     51       setter. If this isn't possible, we do a static_cast. This however can only be 
     52       done inside the streamprocessor that handles the specific sub-class types of  
     53       the ports. i.e. by design you should make sure that the static_cast will be 
     54       OK. 
     55        
     56 \todo rework the implementation into something more beautifull 
    4257*/ 
    4358class Port { 
     
    4762         
    4863        /*! 
    49         \brief Specifies the buffering type for ports 
     64        \brief Specifies the buffer type for ports 
     65         
     66        A PointerBuffer uses the getBufferAddress() and setBufferAddres() interface 
     67        A Ringbuffer uses the read/write interface 
    5068        */ 
    5169        enum E_BufferType { 
    52                 E_PacketBuffered, ///< the port is to be processed for every packet 
    53                 E_PeriodBuffered, ///< the port is to be processed after a period of frames 
    54 //              E_SampleBuffered ///< the port is to be processed after each frame (sample) 
     70                E_PointerBuffer,  
     71                E_RingBuffer 
     72        }; 
     73         
     74        /*! 
     75        \brief Specifies the signalling type for ports 
     76        */ 
     77        enum E_SignalType { 
     78                E_PacketSignalled, ///< the port is to be processed for every packet 
     79                E_PeriodSignalled, ///< the port is to be processed after a period of frames 
     80//              E_SampleSignalled ///< the port is to be processed after each frame (sample) 
    5581        }; 
    5682 
     
    6187                E_Float, 
    6288                E_Int24, 
    63                 E_Byte
     89                E_MidiEvent
    6490                E_Default, 
    6591        }; 
     
    82108        }; 
    83109 
    84         Port(std::string name, enum E_BufferType type, unsigned int buffsize,  
    85              enum E_DataType datatype, enum E_PortType porttype, enum E_Direction direction); 
    86               
    87         Port(std::string name, enum E_BufferType type, unsigned int buffsize,  
    88              enum E_DataType datatype, void *externalbuffer, enum E_PortType porttype, enum E_Direction direction); 
     110        Port(std::string name, enum E_PortType porttype, enum E_Direction direction); 
    89111 
    90112        virtual ~Port()  
    91113          {}; 
     114         
     115         
     116        /// Enable the port. (this can be called anytime) 
     117        void enable()  {m_enabled=true;}; 
     118        /// Disable the port. (this can be called anytime) 
     119        void disable() {m_enabled=false;}; 
     120        /// is the port enabled? (this can be called anytime) 
     121        bool isEnabled() {return m_enabled;}; 
     122 
     123        /*! 
     124        \brief Initialize the port 
     125        */ 
     126        bool init(); 
     127         
     128        bool prepare() {return true;}; 
     129        bool reset() {return true;}; 
    92130 
    93131        std::string getName() {return m_Name;}; 
    94         void setName(std::string name) {m_Name=name;}; 
    95  
    96         void enable()  {m_enabled=true;}; 
    97         void disable() {m_enabled=false;}; 
    98         bool isEnabled() {return m_enabled;}; 
    99  
    100         enum E_BufferType getBufferType() {return m_BufferType;}; 
    101  
    102  
    103         enum E_DataType getDataType() {return m_datatype;}; 
    104         bool setDataType(enum E_DataType datatype); 
    105  
    106         enum E_PortType getPortType() {return m_porttype;}; 
    107         enum E_Direction getDirection() {return m_direction;}; 
    108  
    109         // NOT THREAD SAFE! 
    110         // attaches a user buffer to the port. 
    111         // deallocates the internal buffer, if there was one 
    112         // buffersize is in 'events' 
    113  
    114 //      int attachBuffer(void *buff); 
    115  
    116         // detach the user buffer, allocates an internal buffer 
    117 //      int detachBuffer(); 
     132        bool setName(std::string name); 
    118133 
    119134        /** 
     
    122137         */ 
    123138        unsigned int getEventSize(); 
    124          
     139 
     140        /** 
     141         * \brief sets the event type for the port buffer 
     142         * 
     143         * \note use before calling init() 
     144         */ 
     145        virtual bool setDataType(enum E_DataType); 
     146         
     147        enum E_DataType getDataType() {return m_DataType;}; 
     148         
     149        /** 
     150         * \brief sets the event type for the port buffer 
     151         * 
     152         * \note use before calling init() 
     153         */ 
     154        virtual bool setSignalType(enum E_SignalType ); 
     155         
     156        enum E_SignalType getSignalType() {return m_SignalType;}; ///< returns the signalling type of the port 
     157         
     158        /** 
     159         * \brief sets the buffer type for the port 
     160         * 
     161         * \note use before calling init() 
     162         */ 
     163        virtual bool setBufferType(enum E_BufferType ); 
     164         
     165        enum E_BufferType getBufferType() {return m_BufferType;}; ///< returns the buffer type of the port 
     166 
     167        enum E_PortType getPortType() {return m_PortType;}; ///< returns the port type (is fixed) 
     168        enum E_Direction getDirection() {return m_Direction;}; ///< returns the direction (is fixed) 
     169 
    125170        /** 
    126171         * \brief returns the size of the port buffer 
     
    140185         * if there is an internal buffer, it will be resized 
    141186         * 
    142          */ 
    143         bool setBufferSize(unsigned int); 
     187         * \note use before calling init() 
     188         */ 
     189        virtual bool setBufferSize(unsigned int); 
     190         
     191        /** 
     192         * \brief use an external buffer (or not) 
     193         * 
     194         * \note use before calling init() 
     195         */ 
     196        virtual bool useExternalBuffer(bool b); 
     197         
     198        void setExternalBufferAddress(void *buff); 
    144199 
    145200        // FIXME: this is not really OO, but for performance??? 
    146         void *getBufferAddress() {return m_buffer;}; 
    147         void setBufferAddress(void *buff) {m_buffer=buff;}; 
     201        void *getBufferAddress(); 
     202 
     203        // TODO: extend this with a blocking interface 
     204        bool writeEvent(void *event); ///< write one event 
     205        bool readEvent(void *event); ///< read one event 
     206        int writeEvents(void *event, unsigned int nevents); ///< write multiple events 
     207        int readEvents(void *event, unsigned int nevents); ///< read multiple events 
    148208 
    149209        virtual void setVerboseLevel(int l); 
     
    152212        std::string m_Name; ///< Port name, [at construction] 
    153213 
     214        enum E_SignalType m_SignalType; ///< Signalling type, [at construction] 
    154215        enum E_BufferType m_BufferType; ///< Buffer type, [at construction] 
    155216 
    156217        bool m_enabled; ///< is the port enabled?, [anytime] 
    157          
    158         /** 
    159          * \brief size of the buffer 
    160          * 
    161          * counted in number of E_DataType units, not in bytes 
    162          * 
    163          * [] 
    164          */ 
     218        bool m_initialized; ///< is the port initialized? [after init()] 
     219 
    165220        unsigned int m_buffersize;  
    166  
    167         enum E_DataType m_datatype; ///< size of the buffer, number of E_DataType units [] 
    168         enum E_PortType m_porttype; 
    169         enum E_Direction m_direction; 
     221        unsigned int m_eventsize;  
     222 
     223        enum E_DataType m_DataType; 
     224        enum E_PortType m_PortType; 
     225        enum E_Direction m_Direction; 
    170226 
    171227        void *m_buffer; 
    172         bool m_buffer_attached; 
     228        freebob_ringbuffer_t *m_ringbuffer; 
     229        bool m_use_external_buffer; 
    173230 
    174231        bool allocateInternalBuffer(); 
    175232        void freeInternalBuffer(); 
    176  
    177         // call this when the event size is changed 
    178         virtual bool eventSizeChanged(); ///< this is called whenever the event size changes. 
     233         
     234        bool allocateInternalRingBuffer(); 
     235        void freeInternalRingBuffer(); 
    179236 
    180237    DECLARE_DEBUG_MODULE; 
     
    191248public: 
    192249 
    193         AudioPort(std::string name, unsigned int buffsize, enum E_Direction direction)  
    194           : Port(name, E_PeriodBuffered, buffsize, E_Int24, E_Audio, direction) 
     250        AudioPort(std::string name, enum E_Direction direction)  
     251          : Port(name, E_Audio, direction) 
    195252        {}; 
    196253 
    197         AudioPort(std::string name, enum E_BufferType type, unsigned int buffsize,  
    198                   enum E_Direction direction)  
    199           : Port(name, type, buffsize, E_Int24, E_Audio, direction) 
    200         {}; 
    201         AudioPort(std::string name, enum E_BufferType type, unsigned int buffsize,  
    202                   void *externalbuffer, enum E_Direction direction)  
    203           : Port(name, type, buffsize, E_Int24, externalbuffer, E_Audio, direction) 
    204         {}; 
    205  
    206         AudioPort(std::string name, enum E_DataType datatype, 
    207                   enum E_BufferType type, unsigned int buffsize, enum E_Direction direction)  
    208           : Port(name, type, buffsize, datatype, E_Audio, direction) 
    209         {}; 
    210         AudioPort(std::string name, enum E_DataType datatype,  
    211                   enum E_BufferType type, unsigned int buffsize, void *externalbuffer,  
    212                   enum E_Direction direction)  
    213           : Port(name, type, buffsize, datatype, externalbuffer, E_Audio, direction) 
    214         {}; 
    215  
    216254        virtual ~AudioPort() {}; 
    217255 
    218256protected: 
    219         enum E_DataType m_DataType; 
    220257 
    221258   
     
    231268public: 
    232269 
    233         MidiPort(std::string name, unsigned int buffsize, enum E_Direction direction)  
    234           : Port(name, E_PacketBuffered, buffsize, E_Byte, E_Midi, direction) 
     270        MidiPort(std::string name, enum E_Direction direction)  
     271          : Port(name, E_Midi, direction) 
    235272        {}; 
    236273        virtual ~MidiPort() {}; 
     
    238275 
    239276protected: 
    240         enum E_DataType m_DataType; 
    241277 
    242278 
     
    252288public: 
    253289 
    254         ControlPort(std::string name, unsigned int buffsize, enum E_Direction direction)  
    255           : Port(name, E_PeriodBuffered, buffsize, E_Int24, E_Control, direction) 
     290        ControlPort(std::string name, enum E_SignalType type, enum E_BufferType buffertype, enum E_Direction direction)  
     291          : Port(name, E_Control, direction) 
    256292        {}; 
    257293        virtual ~ControlPort() {}; 
  • branches/libfreebob-2.0/src/libstreaming/PortManager.cpp

    r225 r227  
    4444} 
    4545 
    46 bool PortManager::setPortBuffersize(unsigned int newsize) { 
    47         debugOutput( DEBUG_LEVEL_VERBOSE, "setting port buffer size to %d\n",newsize); 
    48  
    49     for ( PortVectorIterator it = m_PacketPorts.begin(); 
    50           it != m_PacketPorts.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     for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    60           it != m_PeriodPorts.end(); 
    61           ++it ) 
    62     { 
    63                 if(!(*it)->setBufferSize(newsize)) { 
    64                         debugFatal("Could not set buffer size for port %s\n",(*it)->getName().c_str()); 
    65                         return false; 
    66                 } 
    67     } 
    68  
    69 //     for ( PortVectorIterator it = m_SamplePorts.begin(); 
    70 //           it != m_SamplePorts.end(); 
    71 //           ++it ) 
    72 //     { 
    73 /*              if(!(*it)->setBufferSize(newsize)) { 
    74                         debugFatal("Could not set buffer size for port %s\n",(*it)->getName().c_str()); 
    75                         return false; 
    76                 }*/ 
    77 //     } 
    78 //      debugOutput( DEBUG_LEVEL_VERBOSE, " => port not found\n"); 
    79  
    80         return true; //not found 
    81  
    82 
    83  
    84 int PortManager::addPort(Port *port) 
     46// bool PortManager::setPortBuffersize(unsigned int newsize) { 
     47//      debugOutput( DEBUG_LEVEL_VERBOSE, "setting port buffer size to %d\n",newsize); 
     48//  
     49//  
     50//      for ( PortVectorIterator it = m_Ports.begin(); 
     51//        it != m_Ports.end(); 
     52//        ++it ) 
     53//      { 
     54//              if(!(*it)->setBufferSize(newsize)) { 
     55//                      debugFatal("Could not set buffer size for port %s\n",(*it)->getName().c_str()); 
     56//                      return false; 
     57//              } 
     58//      } 
     59//  
     60//      return true; //not found 
     61//  
     62// } 
     63 
     64/** 
     65 *  
     66 * @param port  
     67 * @return  
     68 */ 
     69bool PortManager::addPort(Port *port) 
    8570{ 
    86         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 
    8771        assert(port); 
    8872 
    89         port->setVerboseLevel(getDebugLevel()); 
    90  
    91         switch(port->getBufferType()) { 
    92         case (Port::E_PacketBuffered): 
    93                 debugOutput( DEBUG_LEVEL_VERBOSE, "Adding packet buffered port %s\n",port->getName().c_str()); 
    94                 m_PacketPorts.push_back(port); 
    95                 break; 
    96         case Port::E_PeriodBuffered: 
    97                 debugOutput( DEBUG_LEVEL_VERBOSE, "Adding period buffered port %s\n",port->getName().c_str()); 
    98                 m_PeriodPorts.push_back(port); 
    99                 break; 
    100 /*      case Port::E_SampleBuffered: 
    101                 m_SamplePorts.push_back(port); 
    102                 break;*/ 
    103         default: 
    104                 debugFatal("Unsupported port type!"); 
    105                 return -1; 
    106         } 
    107  
    108         return 0; 
    109 
    110  
    111 int PortManager::deletePort(Port *port) 
     73        debugOutput( DEBUG_LEVEL_VERBOSE, "Adding port %s\n",port->getName().c_str()); 
     74        m_Ports.push_back(port); 
     75 
     76        return true; 
     77
     78 
     79bool PortManager::deletePort(Port *port) 
    11280{ 
    113         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 
    11481        assert(port); 
    11582        debugOutput( DEBUG_LEVEL_VERBOSE, "deleting port %s\n",port->getName().c_str()); 
    11683 
    117     for ( PortVectorIterator it = m_PacketPorts.begin(); 
    118           it != m_PacketPorts.end(); 
    119           ++it ) 
    120     { 
    121         if ( *it == port ) {  
    122             m_PacketPorts.erase(it); 
    123                         delete *it; 
    124                         return 0; 
    125         } 
    126     } 
    127  
    128     for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    129           it != m_PeriodPorts.end(); 
    130           ++it ) 
    131     { 
    132         if ( *it == port ) {  
    133             m_PeriodPorts.erase(it); 
    134                         delete *it; 
    135                         return 0; 
    136         } 
    137     } 
    138  
    139 //     for ( PortVectorIterator it = m_SamplePorts.begin(); 
    140 //           it != m_SamplePorts.end(); 
    141 //           ++it ) 
    142 //     { 
    143 //         if ( *it == port ) {  
    144 //             m_SamplePorts.erase(it); 
    145 //                      return 0; 
    146 //         } 
    147 //     } 
    148 //      debugOutput( DEBUG_LEVEL_VERBOSE, " => port not found\n"); 
    149  
    150         return -1; //not found 
     84        for ( PortVectorIterator it = m_Ports.begin(); 
     85          it != m_Ports.end(); 
     86          ++it ) 
     87        { 
     88                if(*it == port) { 
     89                        m_Ports.erase(it); 
     90//                      delete *it; 
     91                        return true; 
     92                } 
     93        } 
     94 
     95        debugOutput( DEBUG_LEVEL_VERBOSE, "port %s not found \n",port->getName().c_str()); 
     96         
     97        return false; //not found 
    15198 
    15299} 
     
    154101void PortManager::deleteAllPorts() 
    155102{ 
    156         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 
    157103        debugOutput( DEBUG_LEVEL_VERBOSE, "deleting all ports\n"); 
    158104 
    159     for ( PortVectorIterator it = m_PacketPorts.begin(); 
    160           it != m_PacketPorts.end(); 
    161           ++it ) 
    162     { 
    163         m_PacketPorts.erase(it); 
    164                 delete *it; 
    165     } 
    166  
    167     for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    168           it != m_PeriodPorts.end(); 
    169           ++it ) 
    170     { 
    171         m_PeriodPorts.erase(it); 
    172                 delete *it; 
    173     } 
    174  
    175 //     for ( PortVectorIterator it = m_SamplePorts.begin(); 
    176 //           it != m_SamplePorts.end(); 
    177 //           ++it ) 
    178 //     { 
    179 //          m_SamplePorts.erase(it); 
    180 //                      delete *it; 
    181 //     } 
     105        for ( PortVectorIterator it = m_Ports.begin(); 
     106          it != m_Ports.end(); 
     107          ++it ) 
     108        { 
     109                m_Ports.erase(it); 
     110//              delete *it; 
     111        } 
    182112 
    183113        return; 
     
    188118        int count=0; 
    189119 
    190     for ( PortVectorIterator it = m_PacketPorts.begin(); 
    191           it != m_PacketPorts.end(); 
    192           ++it ) 
    193    
    194         if ( (*it)->getPortType() == type ) {  
     120       for ( PortVectorIterator it = m_Ports.begin(); 
     121         it != m_Ports.end(); 
     122         ++it ) 
     123       
     124               if ( (*it)->getPortType() == type ) {  
    195125                        count++; 
    196         } 
    197     } 
    198  
    199     for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    200           it != m_PeriodPorts.end(); 
    201           ++it ) 
    202     { 
    203         if ( (*it)->getPortType() == type ) {  
    204                         count++; 
    205         } 
    206     } 
    207  
    208 //     for ( PortVectorIterator it = m_SamplePorts.begin(); 
    209 //           it != m_SamplePorts.end(); 
    210 //           ++it ) 
    211 //     { 
    212 //         if ( (*it)->getPortType() == type ) {  
    213 //                      count++; 
    214 //         } 
    215 //         } 
    216 //     } 
    217  
     126                } 
     127        } 
    218128        return count; 
    219129} 
     
    222132        int count=0; 
    223133 
    224  
    225          
    226         count+=m_PacketPorts.size(); 
    227         count+=m_PeriodPorts.size(); 
    228 //      count+=m_SamplePorts.size(); 
     134        count+=m_Ports.size(); 
    229135 
    230136        return count; 
     
    233139Port * PortManager::getPortAtIdx(unsigned int index) { 
    234140 
    235         if (index<m_PacketPorts.size()) { 
    236                 return m_PacketPorts.at(index); 
    237         } 
    238         index -= m_PacketPorts.size(); 
    239  
    240         if (index<m_PeriodPorts.size()) { 
    241                 return m_PeriodPorts.at(index); 
    242         } 
    243  
    244 //      index -= m_PeriodPorts.size(); 
    245 //  
    246 //      if (index<m_SamplePorts.size()) { 
    247 //              return m_SamplePorts.at(index); 
    248 //      } 
    249  
    250         return 0; 
     141        return m_Ports.at(index); 
    251142 
    252143} 
     
    256147        setDebugLevel(i); 
    257148 
    258     for ( PortVectorIterator it = m_PacketPorts.begin(); 
    259           it != m_PacketPorts.end(); 
    260           ++it ) 
    261     { 
    262         (*it)->setVerboseLevel(i); 
    263     } 
    264  
    265     for ( PortVectorIterator it = m_PeriodPorts.begin(); 
    266           it != m_PeriodPorts.end(); 
    267           ++it ) 
    268     { 
    269         (*it)->setVerboseLevel(i); 
    270     } 
    271  
    272 //     for ( PortVectorIterator it = m_SamplePorts.begin(); 
    273 //           it != m_SamplePorts.end(); 
    274 //           ++it ) 
    275 //     { 
    276 //         (*it)->setVerboseLevel(i); 
    277 //     } 
     149        for ( PortVectorIterator it = m_Ports.begin(); 
     150          it != m_Ports.end(); 
     151          ++it ) 
     152        { 
     153                (*it)->setVerboseLevel(i); 
     154        } 
    278155 
    279156} 
     
    281158 
    282159bool PortManager::resetPorts() { 
     160        debugOutput( DEBUG_LEVEL_VERBOSE, "reset ports\n"); 
     161         
     162        for ( PortVectorIterator it = m_Ports.begin(); 
     163          it != m_Ports.end(); 
     164          ++it ) 
     165        { 
     166                if(!(*it)->reset()) { 
     167                        debugFatal("Could not reset port %s",(*it)->getName().c_str()); 
     168                        return false; 
     169                } 
     170        } 
    283171        return true; 
    284172} 
    285173 
    286174bool PortManager::initPorts() { 
     175        debugOutput( DEBUG_LEVEL_VERBOSE, "init ports\n"); 
     176         
     177        for ( PortVectorIterator it = m_Ports.begin(); 
     178          it != m_Ports.end(); 
     179          ++it ) 
     180        { 
     181                if(!(*it)->init()) { 
     182                        debugFatal("Could not init port %s",(*it)->getName().c_str()); 
     183                        return false; 
     184                } 
     185        } 
    287186        return true; 
    288187} 
    289188 
    290189bool PortManager::preparePorts() { 
    291         return true; 
    292 
    293  
    294 
     190        debugOutput( DEBUG_LEVEL_VERBOSE, "preparing ports\n"); 
     191         
     192        // clear the cache lists 
     193        m_PeriodPorts.clear(); 
     194        m_PacketPorts.clear(); 
     195         
     196        for ( PortVectorIterator it = m_Ports.begin(); 
     197          it != m_Ports.end(); 
     198          ++it ) 
     199        { 
     200                if(!(*it)->prepare()) { 
     201                        debugFatal("Could not prepare port %s",(*it)->getName().c_str()); 
     202                        return false; 
     203                } 
     204                 
     205                // now prepare the cache lists 
     206                switch((*it)->getSignalType()) { 
     207                        case Port::E_PacketSignalled: 
     208                                m_PacketPorts.push_back(*it); 
     209                                break; 
     210                        case Port::E_PeriodSignalled: 
     211                                m_PeriodPorts.push_back(*it); 
     212                                break; 
     213                        default: 
     214                                debugWarning("%s has unsupported port type\n", 
     215                                             (*it)->getName().c_str());  
     216                        break; 
     217                } 
     218        } 
     219         
     220         
     221         
     222        return true; 
     223
     224 
     225
  • branches/libfreebob-2.0/src/libstreaming/PortManager.h

    r225 r227  
    5252        virtual ~PortManager(); 
    5353 
    54         virtual int addPort(Port *port); 
    55         virtual int deletePort(Port *port); 
     54        virtual bool addPort(Port *port); 
     55        virtual bool deletePort(Port *port); 
    5656        virtual void deleteAllPorts(); 
    5757 
     
    5959        int getPortCount(); 
    6060 
    61       virtual bool setPortBuffersize(unsigned int newsize); 
     61//    virtual bool setPortBuffersize(unsigned int newsize); 
    6262 
    6363        Port *getPortAtIdx(unsigned int index); 
     
    7070 
    7171protected: 
     72        PortVector m_Ports; 
    7273        PortVector m_PacketPorts; 
    7374        PortVector m_PeriodPorts; 
  • branches/libfreebob-2.0/src/libstreaming/StreamProcessorManager.cpp

    r225 r227  
    149149{ 
    150150        debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 
    151          
     151 
     152        // and the tread that runs the runner 
     153        streamingThread=new FreebobPosixThread(this); 
     154        if(!streamingThread) { 
     155                debugFatal("Could not create streaming thread\n"); 
     156                return false; 
     157        } 
     158 
    152159        m_isoManager=new IsoHandlerManager(); 
    153160         
     
    162169        } 
    163170 
    164          
    165171        if(sem_init(&m_period_semaphore, 0, 0)) { 
    166172                debugFatal( "Cannot init packet transfer semaphore\n"); 
     
    188194                it != m_ReceiveProcessors.end(); 
    189195                ++it ) { 
    190                         if(!(*it)->setPortBuffersize(m_period)) { 
    191                                 debugFatal( " could not set buffer size (%p)...\n",(*it)); 
    192                                 return false; 
    193                                  
    194                         } 
    195                          
    196196                        if(!(*it)->prepare()) { 
    197197                                debugFatal(  " could not prepare (%p)...\n",(*it)); 
     
    199199                                 
    200200                        } 
    201                          
    202                         if (!m_isoManager->registerStream(*it)) { 
    203                                 debugOutput(DEBUG_LEVEL_VERBOSE,"Could not register receive stream processor (%p) with the Iso manager\n",*it); 
    204                                 return false; 
    205                         } 
    206                          
    207                          
    208201                } 
    209202 
     
    212205                it != m_TransmitProcessors.end(); 
    213206                ++it ) { 
    214                         if(!(*it)->setPortBuffersize(m_period)) { 
    215                                 debugFatal( " could not set buffer size (%p)...\n",(*it)); 
    216                                 return false; 
    217                          
    218                         } 
    219                          
    220207                        if(!(*it)->prepare()) { 
    221208                                debugFatal( " could not prepare (%p)...\n",(*it)); 
     
    224211                        } 
    225212                         
    226                         if (!m_isoManager->registerStream(*it)) { 
    227                                 debugOutput(DEBUG_LEVEL_VERBOSE,"Could not register transmit stream processor (%p) with the Iso manager\n",*it); 
    228                                 return false; 
    229                         } 
    230                          
    231                 } 
    232  
    233         if (!m_isoManager->prepare()) { 
    234                 debugFatal("Could not prepare isoManager\n"); 
    235                 return false; 
    236         } 
     213                } 
    237214 
    238215        return true; 
     
    303280        assert(m_isoManager); 
    304281         
    305         debugOutput( DEBUG_LEVEL_VERBOSE, " Iso handlers...\n"); 
     282        debugOutput( DEBUG_LEVEL_VERBOSE, "Creating handlers for the StreamProcessors...\n"); 
     283        debugOutput( DEBUG_LEVEL_VERBOSE, " Receive processors...\n"); 
     284        for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     285                it != m_ReceiveProcessors.end(); 
     286                ++it ) { 
     287                        if (!m_isoManager->registerStream(*it)) { 
     288                                debugOutput(DEBUG_LEVEL_VERBOSE,"Could not register receive stream processor (%p) with the Iso manager\n",*it); 
     289                                return false; 
     290                        } 
     291                         
     292                         
     293                } 
     294 
     295        debugOutput( DEBUG_LEVEL_VERBOSE, " Transmit processors...\n"); 
     296        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     297                it != m_TransmitProcessors.end(); 
     298                ++it ) { 
     299                        if (!m_isoManager->registerStream(*it)) { 
     300                                debugOutput(DEBUG_LEVEL_VERBOSE,"Could not register transmit stream processor (%p) with the Iso manager\n",*it); 
     301                                return false; 
     302                        } 
     303                         
     304                } 
     305 
     306        debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing IsoHandlerManager...\n"); 
     307        if (!m_isoManager->prepare()) { 
     308                debugFatal("Could not prepare isoManager\n"); 
     309                return false; 
     310        } 
     311 
     312        debugOutput( DEBUG_LEVEL_VERBOSE, "Starting IsoHandler...\n"); 
    306313        if (!m_isoManager->startHandlers()) { 
    307314                debugFatal("Could not start handlers...\n"); 
     
    309316        } 
    310317         
    311         debugOutput( DEBUG_LEVEL_VERBOSE, " waiting for all StreamProcessors to start running...\n"); 
     318        debugOutput( DEBUG_LEVEL_VERBOSE, "Starting streaming thread...\n"); 
     319         
     320        // start the runner thread 
     321        streamingThread->Start(); 
     322         
     323        debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for all StreamProcessors to start running...\n"); 
    312324        // we have to wait untill all streamprocessors indicate that they are running 
    313325        // i.e. that there is actually some data stream flowing 
     
    357369        } 
    358370         
    359         debugOutput( DEBUG_LEVEL_VERBOSE, " StreamProcessors running...\n"); 
    360         debugOutput( DEBUG_LEVEL_VERBOSE, " Resetting frame counters...\n"); 
     371        debugOutput( DEBUG_LEVEL_VERBOSE, "StreamProcessors running...\n"); 
     372        debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting frame counters...\n"); 
    361373         
    362374        // now we reset the frame counters 
     
    384396        } 
    385397         
    386         debugOutput( DEBUG_LEVEL_VERBOSE, " Enabling StreamProcessors...\n"); 
     398        debugOutput( DEBUG_LEVEL_VERBOSE, "Enabling StreamProcessors...\n"); 
    387399        // and we enable the streamprocessors 
    388400        for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     
    397409                (*it)->enable(); 
    398410        } 
    399          
    400411         
    401412        // dump the iso stream information when in verbose mode 
     
    404415        } 
    405416         
    406          
    407417} 
    408418 
     
    410420        debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 
    411421        assert(m_isoManager); 
     422        assert(streamingThread); 
     423         
     424        streamingThread->Stop(); 
     425         
    412426        return m_isoManager->stopHandlers(); 
     427         
    413428} 
    414429 
  • branches/libfreebob-2.0/src/libstreaming/StreamProcessorManager.h

    r225 r227  
    3131#include "../debugmodule/debugmodule.h" 
    3232#include "FreebobThread.h" 
     33#include "FreebobPosixThread.h" 
    3334#include <semaphore.h> 
    3435#include "Port.h" 
     
    122123        IsoHandlerManager *m_isoManager; 
    123124 
     125        FreebobPosixThread *streamingThread; 
     126 
    124127    DECLARE_DEBUG_MODULE; 
    125128 
  • branches/libfreebob-2.0/tests/streaming/test-isohandling.cpp

    r225 r227  
    122122        AmdtpAudioPort *p1=new AmdtpAudioPort( 
    123123                           std::string("Test port 1"),  
    124                            AmdtpAudioPort::E_Int24, 
    125                            AmdtpAudioPort::E_PeriodBuffered,  
    126                            512, 
    127124                           AmdtpAudioPort::E_Capture,  
    128125                           1,  
     
    135132                return -1; 
    136133        } 
     134 
     135        p1->setBufferSize(512); 
    137136 
    138137        printf("----------------------\n");