root/branches/libfreebob-2.0/src/libstreaming/AmdtpStreamProcessor.cpp

Revision 244, 46.1 kB (checked in by pieterpalmers, 18 years ago)

- first try to implement the SYT synchronisation.

Not working yet.

- committing to spend some time to get the Motu people going.

Line 
1 /* $Id$ */
2
3 /*
4  *   FreeBob Streaming API
5  *   FreeBob = Firewire (pro-)audio for linux
6  *
7  *   http://freebob.sf.net
8  *
9  *   Copyright (C) 2005,2006 Pieter Palmers <pieterpalmers@users.sourceforge.net>
10  *
11  *   This program is free software {} you can redistribute it and/or modify
12  *   it under the terms of the GNU General Public License as published by
13  *   the Free Software Foundation {} either version 2 of the License, or
14  *   (at your option) any later version.
15  *
16  *   This program is distributed in the hope that it will be useful,
17  *   but WITHOUT ANY WARRANTY {} without even the implied warranty of
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *   GNU General Public License for more details.
20  *
21  *   You should have received a copy of the GNU General Public License
22  *   along with this program {} if not, write to the Free Software
23  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  *
25  *
26  *
27  */
28
29 #include "AmdtpStreamProcessor.h"
30 #include "Port.h"
31 #include "AmdtpPort.h"
32
33 #include <netinet/in.h>
34 #include <assert.h>
35
36 #define CYCLE_COUNTER_GET_SECS(x)   (((x & 0xFE000000) >> 25))
37 #define CYCLE_COUNTER_GET_CYCLES(x) (((x & 0x01FFF000) >> 12))
38 #define CYCLE_COUNTER_GET_TICKS(x)  (((x & 0x00000FFF)))
39 #define CYCLE_COUNTER_TO_TICKS(x) ((CYCLE_COUNTER_GET_SECS(x)   * 24576000) +\
40                                    (CYCLE_COUNTER_GET_CYCLES(x) *     3072) +\
41                                    (CYCLE_COUNTER_GET_TICKS(x)            ))
42
43 // this is one milisecond of processing delay
44 #define TICKS_PER_SECOND 24576000
45 #define RECEIVE_PROCESSING_DELAY (TICKS_PER_SECOND / 500)
46
47 namespace FreebobStreaming {
48
49 IMPL_DEBUG_MODULE( AmdtpTransmitStreamProcessor, AmdtpTransmitStreamProcessor, DEBUG_LEVEL_NORMAL );
50 IMPL_DEBUG_MODULE( AmdtpReceiveStreamProcessor, AmdtpReceiveStreamProcessor, DEBUG_LEVEL_NORMAL );
51
52
53 /* transmit */
54 AmdtpTransmitStreamProcessor::AmdtpTransmitStreamProcessor(int port, int framerate, int dimension)
55         : TransmitStreamProcessor(port, framerate), m_dimension(dimension) {
56
57
58 }
59
60 AmdtpTransmitStreamProcessor::~AmdtpTransmitStreamProcessor() {
61         freebob_ringbuffer_free(m_event_buffer);
62         free(m_cluster_buffer);
63 }
64
65 bool AmdtpTransmitStreamProcessor::init() {
66
67         debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing (%p)...\n");
68         // call the parent init
69         // this has to be done before allocating the buffers,
70         // because this sets the buffersizes from the processormanager
71         if(!TransmitStreamProcessor::init()) {
72                 debugFatal("Could not do base class init (%p)\n",this);
73                 return false;
74         }
75        
76
77         return true;
78 }
79
80 void AmdtpTransmitStreamProcessor::setVerboseLevel(int l) {
81         setDebugLevel(l);
82         TransmitStreamProcessor::setVerboseLevel(l);
83 }
84
85
86 enum raw1394_iso_disposition
87 AmdtpTransmitStreamProcessor::getPacket(unsigned char *data, unsigned int *length,
88                       unsigned char *tag, unsigned char *sy,
89                       int cycle, unsigned int dropped, unsigned int max_length) {
90
91         struct iec61883_packet *packet = (struct iec61883_packet *) data;
92        
93        
94         // signal that we are running (a transmit stream is always 'runnable')
95         m_running=true;
96        
97         // don't process the stream when it is not enabled.
98         // however, we do have to generate (semi) valid packets
99         // that means that we'll send NODATA packets FIXME: check!!
100         if(m_disabled) {
101                 iec61883_cip_fill_header_nodata(getNodeId(), &m_cip_status, packet);
102                 *length = 0; // this is to disable sending
103                 *tag = IEC61883_TAG_WITH_CIP;
104                 *sy = 0;
105                 return RAW1394_ISO_OK;
106         }
107        
108      debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "get packet...\n");
109        
110         // keep the old cip, in case we don't have enough events left in the buffer.
111         struct iec61883_cip old_cip;
112         memcpy(&old_cip,&m_cip_status,sizeof(struct iec61883_cip));
113                
114         // construct the packet cip
115         int nevents = iec61883_cip_fill_header (getNodeId(), &m_cip_status, packet);
116
117         enum raw1394_iso_disposition retval = RAW1394_ISO_OK;
118
119         if (!(nevents > 0)) {
120                
121                 if (m_cip_status.mode == IEC61883_MODE_BLOCKING_EMPTY) {
122                         *length = 8;
123                         return RAW1394_ISO_OK ;
124                 }
125                 else {
126                         nevents = m_cip_status.syt_interval;
127                 }
128         }
129        
130         int read_size=nevents*sizeof(quadlet_t)*m_dimension;
131
132         if ((freebob_ringbuffer_read(m_event_buffer,(char *)(data+8),read_size)) <
133                                 read_size)
134         {
135         /* there is no more data in the ringbuffer */
136        
137         /* If there are already more than on period
138         * of frames transfered to the XMIT buffer, there is no xrun.
139         *
140         */
141         if(m_framecounter>m_period) {
142             // we stop processing this untill the next period boundary
143             // that's when new data is ready
144            
145             //connection->pfd->events=0;
146            
147             // reset the cip to the old value
148             memcpy(&m_cip_status,&old_cip,sizeof(struct iec61883_cip));
149
150             // retry this packed
151             retval=RAW1394_ISO_AGAIN;
152             nevents=0;
153             debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "again!\n");
154            
155         } else {
156             debugWarning("Transmit buffer underrun (cycle %d, FC=%d, PC=%d)\n",
157                      cycle, m_framecounter, m_handler->getPacketCount());
158            
159             // signal underrun
160             m_xruns++;
161    
162             retval=RAW1394_ISO_DEFER;
163             *length=0;
164             nevents=0;
165         }
166
167     } else {
168         retval=RAW1394_ISO_OK;
169         *length = read_size + 8;
170        
171         // process all ports that should be handled on a per-packet base
172         // this is MIDI for AMDTP (due to the need of DBC)
173         if (!encodePacketPorts((quadlet_t *)(data+8), nevents, packet->dbc)) {
174             debugWarning("Problem encoding Packet Ports\n");
175         }
176        
177         if (packet->syt != 0xFFFF) {
178              unsigned int m_last_timestamp=ntohs(packet->syt);
179              // reconstruct the top part of the timestamp using the current cycle number
180               m_last_timestamp |= ((cycle << 12) & 0x01FF0000);
181              
182              debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Sent packet with SYT for cycle %2d: %5u ticks (%2u cycles + %04u ticks)\n",
183              cycle,
184              CYCLE_COUNTER_TO_TICKS(m_last_timestamp),
185              CYCLE_COUNTER_GET_CYCLES(m_last_timestamp),
186              CYCLE_COUNTER_GET_TICKS(m_last_timestamp)
187              );
188         }
189     }
190    
191     *tag = IEC61883_TAG_WITH_CIP;
192     *sy = 0;
193    
194     // update the frame counter
195     m_framecounter+=nevents;
196     if(m_framecounter>m_period) {
197        retval=RAW1394_ISO_DEFER;
198     }
199    
200     m_PacketStat.mark(freebob_ringbuffer_read_space(m_event_buffer)/(4*m_dimension));
201        
202     return retval;
203
204 }
205
206 bool AmdtpTransmitStreamProcessor::isOnePeriodReady()
207 {
208     //return true;
209      return (m_framecounter > (int)m_period);
210 }
211  
212 bool AmdtpTransmitStreamProcessor::prefill() {
213     int i=m_nb_buffers;
214     while(i--) {
215         if(!transferSilence(m_period)) {
216             debugFatal("Could not prefill transmit stream\n");
217             return false;
218         }
219     }
220    
221     // and we should also provide enough prefill for the
222     // SYT processing delay
223 /*    if(!transferSilence((m_framerate * RECEIVE_PROCESSING_DELAY)/TICKS_PER_SECOND)) {
224         debugFatal("Could not prefill transmit stream\n");
225         return false;
226     }*/
227    
228     // the framecounter should be pulled back to
229     // make sure the ISO buffering is used
230     // we are using 1 period of iso buffering
231 //     m_framecounter=-m_period;
232    
233     // should this also be pre-buffered?
234     //m_framecounter=-(m_framerate * RECEIVE_PROCESSING_DELAY)/TICKS_PER_SECOND;
235    
236     return true;
237    
238 }
239
240 bool AmdtpTransmitStreamProcessor::reset() {
241
242     debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n");
243
244     // reset the event buffer, discard all content
245     freebob_ringbuffer_reset(m_event_buffer);
246    
247     // reset the statistics
248         m_PeriodStat.reset();
249     m_PacketStat.reset();
250     m_WakeupStat.reset();
251    
252     // reset all non-device specific stuff
253     // i.e. the iso stream and the associated ports
254     if(!TransmitStreamProcessor::reset()) {
255         debugFatal("Could not do base class reset\n");
256         return false;
257     }
258    
259     // we should prefill the event buffer
260     if (!prefill()) {
261         debugFatal("Could not prefill buffers\n");
262         return false;   
263     }
264    
265     return true;
266 }
267
268 bool AmdtpTransmitStreamProcessor::prepare() {
269     m_PeriodStat.setName("XMT PERIOD");
270     m_PacketStat.setName("XMT PACKET");
271     m_WakeupStat.setName("XMT WAKEUP");
272
273     debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing...\n");
274    
275     // prepare all non-device specific stuff
276     // i.e. the iso stream and the associated ports
277     if(!TransmitStreamProcessor::prepare()) {
278         debugFatal("Could not prepare base class\n");
279         return false;
280     }
281    
282     switch (m_framerate) {
283     case 32000:
284         m_syt_interval = 8;
285         m_fdf = IEC61883_FDF_SFC_32KHZ;
286         break;
287     case 44100:
288         m_syt_interval = 8;
289         m_fdf = IEC61883_FDF_SFC_44K1HZ;
290         break;
291     default:
292     case 48000:
293         m_syt_interval = 8;
294         m_fdf = IEC61883_FDF_SFC_48KHZ;
295         break;
296     case 88200:
297         m_syt_interval = 16;
298         m_fdf = IEC61883_FDF_SFC_88K2HZ;
299         break;
300     case 96000:
301         m_syt_interval = 16;
302         m_fdf = IEC61883_FDF_SFC_96KHZ;
303         break;
304     case 176400:
305         m_syt_interval = 32;
306         m_fdf = IEC61883_FDF_SFC_176K4HZ;
307         break;
308     case 192000:
309         m_syt_interval = 32;
310         m_fdf = IEC61883_FDF_SFC_192KHZ;
311         break;
312     }
313    
314     iec61883_cip_init (
315         &m_cip_status,
316         IEC61883_FMT_AMDTP,
317         m_fdf,
318         m_framerate,
319         m_dimension,
320         m_syt_interval);
321
322     // allocate the event buffer
323     unsigned int ringbuffer_size_frames=m_nb_buffers * m_period;
324    
325     // add the processing delay
326     ringbuffer_size_frames+=(m_framerate * RECEIVE_PROCESSING_DELAY)/TICKS_PER_SECOND;
327    
328     if( !(m_event_buffer=freebob_ringbuffer_create(
329             (m_dimension * ringbuffer_size_frames) * sizeof(quadlet_t)))) {
330         debugFatal("Could not allocate memory event ringbuffer");
331 //              return -ENOMEM;
332         return false;
333     }
334
335     // allocate the temporary cluster buffer
336     if( !(m_cluster_buffer=(char *)calloc(m_dimension,sizeof(quadlet_t)))) {
337         debugFatal("Could not allocate temporary cluster buffer");
338         freebob_ringbuffer_free(m_event_buffer);
339         return false;
340 //              return -ENOMEM;
341     }
342
343     // set the parameters of ports we can:
344     // we want the audio ports to be period buffered,
345     // and the midi ports to be packet buffered
346     for ( PortVectorIterator it = m_Ports.begin();
347           it != m_Ports.end();
348           ++it )
349     {
350         debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
351         if(!(*it)->setBufferSize(m_period)) {
352             debugFatal("Could not set buffer size to %d\n",m_period);
353             return false;
354         }
355        
356        
357         switch ((*it)->getPortType()) {
358             case Port::E_Audio:
359                 if(!(*it)->setSignalType(Port::E_PeriodSignalled)) {
360                     debugFatal("Could not set signal type to PeriodSignalling");
361                     return false;
362                 }
363                 debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n");
364                 // buffertype and datatype are dependant on the API
365                 if(!(*it)->setBufferType(Port::E_PointerBuffer)) {
366                     debugFatal("Could not set buffer type");
367                     return false;
368                 }
369                 if(!(*it)->useExternalBuffer(true)) {
370                     debugFatal("Could not set external buffer usage");
371                     return false;
372                 }
373                
374                 if(!(*it)->setDataType(Port::E_Float)) {
375                     debugFatal("Could not set data type");
376                     return false;
377                 }
378                
379                
380                 break;
381             case Port::E_Midi:
382                 if(!(*it)->setSignalType(Port::E_PacketSignalled)) {
383                     debugFatal("Could not set signal type to PeriodSignalling");
384                     return false;
385                 }
386                
387                 // we use a timing unit of 10ns
388                 // this makes sure that for the max syt interval
389                 // we don't have rounding, and keeps the numbers low
390                 // we have 1 slot every 8 events
391                 // we have syt_interval events per packet
392                 // => syt_interval/8 slots per packet
393                 // packet rate is 8000pkt/sec => interval=125us
394                 // so the slot interval is (1/8000)/(syt_interval/8)
395                 // or: 1/(1000 * syt_interval) sec
396                 // which is 1e9/(1000*syt_interval) nsec
397                 // or 100000/syt_interval 'units'
398                 // the event interval is fixed to 320us = 32000 'units'
399                 if(!(*it)->useRateControl(true,(100000/m_syt_interval),32000, false)) {
400                     debugFatal("Could not set signal type to PeriodSignalling");
401                     return false;
402                 }
403                
404                 // buffertype and datatype are dependant on the API
405                 debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n");
406                 // buffertype and datatype are dependant on the API
407                 if(!(*it)->setBufferType(Port::E_RingBuffer)) {
408                     debugFatal("Could not set buffer type");
409                     return false;
410                 }
411                 if(!(*it)->setDataType(Port::E_MidiEvent)) {
412                     debugFatal("Could not set data type");
413                     return false;
414                 }
415                 break;
416             default:
417                 debugWarning("Unsupported port type specified\n");
418                 break;
419         }
420     }
421
422     // the API specific settings of the ports should already be set,
423     // as this is called from the processorManager->prepare()
424     // so we can init the ports
425     if(!initPorts()) {
426         debugFatal("Could not initialize ports!\n");
427         return false;
428     }
429
430     if(!preparePorts()) {
431         debugFatal("Could not initialize ports!\n");
432         return false;
433     }
434
435     // we should prefill the event buffer
436     if (!prefill()) {
437         debugFatal("Could not prefill buffers\n");
438         return false;   
439     }
440    
441     debugOutput( DEBUG_LEVEL_VERBOSE, "Prepared for:\n");
442     debugOutput( DEBUG_LEVEL_VERBOSE, " Samplerate: %d, FDF: %d, DBS: %d, SYT: %d\n",
443              m_framerate,m_fdf,m_dimension,m_syt_interval);
444     debugOutput( DEBUG_LEVEL_VERBOSE, " PeriodSize: %d, NbBuffers: %d\n",
445              m_period,m_nb_buffers);
446     debugOutput( DEBUG_LEVEL_VERBOSE, " Port: %d, Channel: %d\n",
447              m_port,m_channel);
448
449     return true;
450
451 }
452
453 bool AmdtpTransmitStreamProcessor::transferSilence(unsigned int size) {
454     /* a naive implementation would look like this: */
455    
456     unsigned int write_size=size*sizeof(quadlet_t)*m_dimension;
457     char *dummybuffer=(char *)calloc(sizeof(quadlet_t),size*m_dimension);
458     transmitSilenceBlock(dummybuffer, size, 0);
459
460     if (freebob_ringbuffer_write(m_event_buffer,(char *)(dummybuffer),write_size) < write_size) {
461         debugWarning("Could not write to event buffer\n");
462     }
463    
464     free(dummybuffer);
465    
466     return true;
467 }
468
469 bool AmdtpTransmitStreamProcessor::transfer() {
470     m_PeriodStat.mark(freebob_ringbuffer_read_space(m_event_buffer)/(4*m_dimension));
471
472     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n");
473     // TODO: improve
474 /* a naive implementation would look like this:
475
476     unsigned int write_size=m_period*sizeof(quadlet_t)*m_dimension;
477     char *dummybuffer=(char *)calloc(sizeof(quadlet_t),m_period*m_dimension);
478     transmitBlock(dummybuffer, m_period, 0, 0);
479
480     if (freebob_ringbuffer_write(m_event_buffer,(char *)(dummybuffer),write_size) < write_size) {
481         debugWarning("Could not write to event buffer\n");
482     }
483
484
485     free(dummybuffer);
486 */
487 /* but we're not that naive anymore... */
488     int xrun;
489     unsigned int offset=0;
490    
491     freebob_ringbuffer_data_t vec[2];
492     // we received one period of frames
493     // this is period_size*dimension of events
494     int events2write=m_period*m_dimension;
495     int bytes2write=events2write*sizeof(quadlet_t);
496
497     /* write events2write bytes to the ringbuffer
498     *  first see if it can be done in one read.
499     *  if so, ok.
500     *  otherwise write up to a multiple of clusters directly to the buffer
501     *  then do the buffer wrap around using ringbuffer_write
502     *  then write the remaining data directly to the buffer in a third pass
503     *  Make sure that we cannot end up on a non-cluster aligned position!
504     */
505     int cluster_size=m_dimension*sizeof(quadlet_t);
506
507     while(bytes2write>0) {
508         int byteswritten=0;
509        
510         unsigned int frameswritten=(m_period*cluster_size-bytes2write)/cluster_size;
511         offset=frameswritten;
512        
513         freebob_ringbuffer_get_write_vector(m_event_buffer, vec);
514            
515         if(vec[0].len==0) { // this indicates a full event buffer
516             debugError("XMT: Event buffer overrun in processor %p\n",this);
517             break;
518         }
519            
520         /* if we don't take care we will get stuck in an infinite loop
521         * because we align to a cluster boundary later
522         * the remaining nb of bytes in one write operation can be
523         * smaller than one cluster
524         * this can happen because the ringbuffer size is always a power of 2
525         */
526         if(vec[0].len<cluster_size) {
527            
528             // encode to the temporary buffer
529             xrun = transmitBlock(m_cluster_buffer, 1, offset);
530            
531             if(xrun<0) {
532                 // xrun detected
533                 debugError("XMT: Frame buffer underrun in processor %p\n",this);
534                 break;
535             }
536                
537             // use the ringbuffer function to write one cluster
538             // the write function handles the wrap around.
539             freebob_ringbuffer_write(m_event_buffer,
540                          m_cluster_buffer,
541                          cluster_size);
542                
543             // we advanced one cluster_size
544             bytes2write-=cluster_size;
545                
546         } else { //
547            
548             if(bytes2write>vec[0].len) {
549                 // align to a cluster boundary
550                 byteswritten=vec[0].len-(vec[0].len%cluster_size);
551             } else {
552                 byteswritten=bytes2write;
553             }
554                
555             xrun = transmitBlock(vec[0].buf,
556                          byteswritten/cluster_size,
557                          offset);
558            
559             if(xrun<0) {
560                     // xrun detected
561                 debugError("XMT: Frame buffer underrun in processor %p\n",this);
562                 break;
563             }
564
565             freebob_ringbuffer_write_advance(m_event_buffer, byteswritten);
566             bytes2write -= byteswritten;
567         }
568
569         // the bytes2write should always be cluster aligned
570         assert(bytes2write%cluster_size==0);
571
572     }
573
574     return true;
575 }
576 /*
577  * write received events to the stream ringbuffers.
578  */
579
580 int AmdtpTransmitStreamProcessor::transmitBlock(char *data,
581                        unsigned int nevents, unsigned int offset)
582 {
583     int problem=0;
584
585     for ( PortVectorIterator it = m_PeriodPorts.begin();
586           it != m_PeriodPorts.end();
587           ++it )
588     {
589
590         if((*it)->isDisabled()) {continue;};
591        
592         //FIXME: make this into a static_cast when not DEBUG?
593
594         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
595         assert(pinfo); // this should not fail!!
596
597         switch(pinfo->getFormat()) {
598         case AmdtpPortInfo::E_MBLA:
599             if(encodePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
600                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str());
601                 problem=1;
602             }
603             break;
604         case AmdtpPortInfo::E_SPDIF: // still unimplemented
605             break;
606         default: // ignore
607             break;
608         }
609     }
610     return problem;
611
612 }
613
614 int AmdtpTransmitStreamProcessor::transmitSilenceBlock(char *data,
615                        unsigned int nevents, unsigned int offset)
616 {
617     int problem=0;
618
619     for ( PortVectorIterator it = m_PeriodPorts.begin();
620           it != m_PeriodPorts.end();
621           ++it )
622     {
623
624         //FIXME: make this into a static_cast when not DEBUG?
625
626         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
627         assert(pinfo); // this should not fail!!
628
629         switch(pinfo->getFormat()) {
630         case AmdtpPortInfo::E_MBLA:
631             if(encodeSilencePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
632                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str());
633                 problem=1;
634             }
635             break;
636         case AmdtpPortInfo::E_SPDIF: // still unimplemented
637             break;
638         default: // ignore
639             break;
640         }
641     }
642     return problem;
643
644 }
645
646 /**
647  * @brief decode a packet for the packet-based ports
648  *
649  * @param data Packet data
650  * @param nevents number of events in data (including events of other ports & port types)
651  * @param dbc DataBlockCount value for this packet
652  * @return true if all successfull
653  */
654 bool AmdtpTransmitStreamProcessor::encodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc)
655 {
656     bool ok=true;
657     char byte;
658    
659     quadlet_t *target_event=NULL;
660     int j;
661    
662     for ( PortVectorIterator it = m_PacketPorts.begin();
663           it != m_PacketPorts.end();
664           ++it )
665     {
666
667 #ifdef DEBUG
668         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
669         assert(pinfo); // this should not fail!!
670
671         // the only packet type of events for AMDTP is MIDI in mbla
672         assert(pinfo->getFormat()==AmdtpPortInfo::E_Midi);
673 #endif
674        
675         AmdtpMidiPort *mp=static_cast<AmdtpMidiPort *>(*it);
676        
677         // we encode this directly (no function call) due to the high frequency
678         /* idea:
679         spec says: current_midi_port=(dbc+j)%8;
680         => if we start at (dbc+stream->location-1)%8 [due to location_min=1],
681         we'll start at the right event for the midi port.
682         => if we increment j with 8, we stay at the right event.
683         */
684         // FIXME: as we know in advance how big a packet is (syt_interval) we can
685         //        predict how much loops will be present here
686         // first prefill the buffer with NO_DATA's on all time muxed channels
687        
688         for(j = (dbc & 0x07)+mp->getLocation()-1; j < nevents; j += 8) {
689        
690             target_event=(quadlet_t *)(data + ((j * m_dimension) + mp->getPosition()));
691            
692             if(mp->canRead()) { // we can send a byte
693                 mp->readEvent(&byte);
694                 *target_event=htonl(
695                     IEC61883_AM824_SET_LABEL((byte)<<16,
696                                              IEC61883_AM824_LABEL_MIDI_1X));
697             } else {
698                 // can't send a byte, either because there is no byte,
699                 // or because this would exceed the maximum rate
700                 *target_event=htonl(
701                     IEC61883_AM824_SET_LABEL(0,IEC61883_AM824_LABEL_MIDI_NO_DATA));
702             }
703         }
704
705     }
706        
707     return ok;
708 }
709
710
711 int AmdtpTransmitStreamProcessor::encodePortToMBLAEvents(AmdtpAudioPort *p, quadlet_t *data,
712                        unsigned int offset, unsigned int nevents)
713 {
714     unsigned int j=0;
715
716     quadlet_t *target_event;
717
718     target_event=(quadlet_t *)(data + p->getPosition());
719
720     switch(p->getDataType()) {
721         default:
722         case Port::E_Int24:
723             {
724                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
725
726                 assert(nevents + offset <= p->getBufferSize());
727
728                 buffer+=offset;
729
730                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
731                     *target_event = htonl((*(buffer) & 0x00FFFFFF) | 0x40000000);
732                     buffer++;
733                     target_event += m_dimension;
734                 }
735             }
736             break;
737         case Port::E_Float:
738             {
739                 const float multiplier = (float)(0x7FFFFF00);
740                 float *buffer=(float *)(p->getBufferAddress());
741
742                 assert(nevents + offset <= p->getBufferSize());
743
744                 buffer+=offset;
745
746                 for(j = 0; j < nevents; j += 1) { // decode max nsamples               
747    
748                     // don't care for overflow
749                     float v = *buffer * multiplier;  // v: -231 .. 231
750                     unsigned int tmp = ((int)v);
751                     *target_event = htonl((tmp >> 8) | 0x40000000);
752                    
753                     buffer++;
754                     target_event += m_dimension;
755                 }
756             }
757             break;
758     }
759
760     return 0;
761 }
762 int AmdtpTransmitStreamProcessor::encodeSilencePortToMBLAEvents(AmdtpAudioPort *p, quadlet_t *data,
763                        unsigned int offset, unsigned int nevents)
764 {
765     unsigned int j=0;
766
767     quadlet_t *target_event;
768
769     target_event=(quadlet_t *)(data + p->getPosition());
770
771     switch(p->getDataType()) {
772         default:
773         case Port::E_Int24:
774         case Port::E_Float:
775             {
776                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
777                     *target_event = htonl(0x40000000);
778                     target_event += m_dimension;
779                 }
780             }
781             break;
782     }
783
784     return 0;
785 }
786
787 /* --------------------- RECEIVE ----------------------- */
788
789 AmdtpReceiveStreamProcessor::AmdtpReceiveStreamProcessor(int port, int framerate, int dimension)
790     : ReceiveStreamProcessor(port, framerate), m_dimension(dimension), m_last_timestamp(0) {
791
792
793 }
794
795 AmdtpReceiveStreamProcessor::~AmdtpReceiveStreamProcessor() {
796     freebob_ringbuffer_free(m_event_buffer);
797     free(m_cluster_buffer);
798
799 }
800
801 bool AmdtpReceiveStreamProcessor::init() {
802     // call the parent init
803     // this has to be done before allocating the buffers,
804     // because this sets the buffersizes from the processormanager
805     if(!ReceiveStreamProcessor::init()) {
806         debugFatal("Could not do base class init (%d)\n",this);
807         return false;
808     }
809
810     return true;
811 }
812
813 enum raw1394_iso_disposition
814 AmdtpReceiveStreamProcessor::putPacket(unsigned char *data, unsigned int length,
815                   unsigned char channel, unsigned char tag, unsigned char sy,
816                   unsigned int cycle, unsigned int dropped) {
817    
818     enum raw1394_iso_disposition retval=RAW1394_ISO_OK;
819    
820     struct iec61883_packet *packet = (struct iec61883_packet *) data;
821     assert(packet);
822    
823     // how are we going to get this right???
824 //     m_running=true;
825    
826     if((packet->fmt == 0x10) && (packet->fdf != 0xFF) && (packet->dbs>0) && (length>=2*sizeof(quadlet_t))) {
827         unsigned int nevents=((length / sizeof (quadlet_t)) - 2)/packet->dbs;
828        
829         // signal that we're running
830                 if(nevents) m_running=true;
831        
832         // don't process the stream when it is not enabled.
833         if(m_disabled) {
834             return RAW1394_ISO_OK;
835         }
836         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "put packet...\n");
837        
838         unsigned int write_size=nevents*sizeof(quadlet_t)*m_dimension;
839         // add the data payload to the ringbuffer
840        
841         if (freebob_ringbuffer_write(m_event_buffer,(char *)(data+8),write_size) < write_size)
842         {
843             debugWarning("Receive buffer overrun (cycle %d, FC=%d, PC=%d)\n",
844                  cycle, m_framecounter, m_handler->getPacketCount());
845             m_xruns++;
846
847             retval=RAW1394_ISO_DEFER;
848         } else {
849             retval=RAW1394_ISO_OK;
850             // process all ports that should be handled on a per-packet base
851             // this is MIDI for AMDTP (due to the need of DBC)
852             if (!decodePacketPorts((quadlet_t *)(data+8), nevents, packet->dbc)) {
853                 debugWarning("Problem decoding Packet Ports\n");
854                 retval=RAW1394_ISO_DEFER;
855             }
856            
857             // do the time stamp processing
858             // put the last time stamp a variable
859             // this will allow us to determine the
860             // actual presentation time later
861             if (packet->syt != 0xFFFF) {
862                  
863                 m_last_timestamp=ntohs(packet->syt);
864                  // reconstruct the top part of the timestamp using the current cycle number
865 //                  m_last_timestamp |= ((cycle << 12) & 0x01FF0000);
866                 unsigned int syt_cycles=CYCLE_COUNTER_GET_CYCLES(m_last_timestamp);
867                 int new_cycles=cycle+(syt_cycles-(cycle & 0xF));
868 //                 m_last_timestamp &= 0xFFF; // keep only the offset
869 //                 m_last_timestamp |= ((new_cycles << 12) & 0x01FFF000); // add the right cycle info
870                  
871                  debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"R-SYT for cycle (%2d %2d)=>%2d: %5uT (%04uC + %04uT) %04X %04X %d\n",
872                  cycle,cycle & 0xF,new_cycles,
873                  CYCLE_COUNTER_TO_TICKS(m_last_timestamp),
874                  CYCLE_COUNTER_GET_CYCLES(m_last_timestamp),
875                  CYCLE_COUNTER_GET_TICKS(m_last_timestamp),
876                  ntohs(packet->syt),m_last_timestamp&0xFFFF, dropped
877                  );
878             }
879         }
880
881         debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
882             "RCV: CH = %d, FDF = %X. SYT = %6d, DBS = %3d, DBC = %3d, FMT = %3d, LEN = %4d (%2d)\n",
883             channel, packet->fdf,
884             packet->syt,
885             packet->dbs,
886             packet->dbc,
887             packet->fmt,
888             length,
889             ((length / sizeof (quadlet_t)) - 2)/packet->dbs);
890        
891         // update the frame counter
892         m_framecounter+=nevents;
893         if(m_framecounter>m_period) {
894            retval=RAW1394_ISO_DEFER;
895            debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"defer!\n");
896         }
897        
898     } else {
899         // discard packet
900         // can be important for sync though
901     }
902    
903     m_PacketStat.mark(freebob_ringbuffer_read_space(m_event_buffer)/(4*m_dimension));
904    
905     return retval;
906 }
907
908 // this uses SYT to determine if one period is ready
909 bool AmdtpReceiveStreamProcessor::isOnePeriodReady() {
910 #if 0 // this code is not ready yet
911
912     // one sample will take a number off cycle counter ticks:
913     // The number of ticks per second is 24576000
914     // The number of samples per second is Fs
915     // therefore the number of ticks per sample is 24576000 / Fs
916     // NOTE: this will be rounded!!
917     float ticks_per_sample=24576000.0/m_framerate;
918
919     // we are allowed to add some constant
920     // processing delay to the transfer delay
921     // being the period size and some fixed delay
922     unsigned int processing_delay=ticks_per_sample*(m_period)+RECEIVE_PROCESSING_DELAY;
923    
924    
925     // the number of events in the buffer is
926     // m_framecounter
927
928     // we have the timestamp of the last event block:
929     // m_last_timestamp
930    
931     // the time at which the beginning of the buffer should be
932     // presented to the audio side is:
933     // m_last_timestamp - (m_framecounter-m_syt_interval)*ticks_per_sample
934    
935     // however we have to make sure that we can transfer at least one period
936     // therefore we first check if this is ok
937    
938      if(m_framecounter > (int)m_period) {
939         // we make this signed, because this can be < 0
940         unsigned int m_last_timestamp_ticks = CYCLE_COUNTER_TO_TICKS(m_last_timestamp);
941        
942         // add the processing delay
943         int ideal_presentation_time = m_last_timestamp_ticks + processing_delay;
944         unsigned int buffer_content_ticks=(int)((m_framecounter-m_syt_interval)*ticks_per_sample);
945        
946         // if the ideal_presentation_time is smaller than buffer_content_ticks, wraparound has occurred
947         // for the cycle part of m_last_timestamp. Therefore add one second worth of ticks
948         // to the cycle counter, as this is the wraparound point.
949         if (ideal_presentation_time < buffer_content_ticks) ideal_presentation_time += 24576000;
950         // we can now safely substract these, it will always be > 0
951         ideal_presentation_time -= buffer_content_ticks;
952        
953         // FIXME: if we are sure, make ideal_presentation_time an unsigned int
954 //         assert(ideal_presentation_time>=0);
955        
956        
957 /*        if(ideal_presentation_time) {
958             debugOutput(DEBUG_LEVEL_VERBOSE, "Presentation time < 0 : %d\n", ideal_presentation_time);
959         }*/
960        
961         unsigned int current_time=m_handler->getCycleCounter() & 0x1FFFFFF;
962         unsigned int current_time_ticks = CYCLE_COUNTER_TO_TICKS(current_time);
963
964         // if the last signalled period lies in the future, we know we had wraparound of the clock
965         // so add one second
966 //         if (current_time_ticks < m_previous_signal_ticks) current_time_ticks += 24576000;
967         debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Periods: %d\n",m_PeriodStat.m_count);
968         debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Timestamp : %10u ticks (%3u secs + %4u cycles + %04u ticks)\n",
969             m_last_timestamp_ticks,
970             CYCLE_COUNTER_GET_SECS(m_last_timestamp),
971             CYCLE_COUNTER_GET_CYCLES(m_last_timestamp),
972             CYCLE_COUNTER_GET_TICKS(m_last_timestamp)
973             );
974         debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"P-TIME    : %10d ticks (%3u secs + %4u cycles + %04u ticks)\n",
975             ideal_presentation_time,
976             ideal_presentation_time/24576000,
977             (ideal_presentation_time/3072) % 8000,
978             ideal_presentation_time%3072
979             );
980         debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Now       : %10u ticks (%3u secs + %4u cycles + %04u ticks)\n",
981             current_time_ticks,
982             CYCLE_COUNTER_GET_SECS(current_time),
983             CYCLE_COUNTER_GET_CYCLES(current_time),
984             CYCLE_COUNTER_GET_TICKS(current_time)
985             );
986        
987         int tmp=ideal_presentation_time-current_time_ticks;
988        
989         // if current_time_ticks wraps around while ahead of the presentation time, we have
990         // a problem.
991         // we know however that we have to wait for at max one buffer + some transmit delay
992         // therefore we clip this value at 0.5 seconds
993         if (tmp > 24576000/2) tmp-=24576000;
994        
995         if(tmp<0) {
996             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"SYT passed (%d ticks too late)\n",-tmp);
997             if (-tmp>1000000) debugWarning("SYT VERY LATE: %d!\n",-tmp);
998             return true;
999         } else {
1000             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Too early wait %d ticks\n",tmp);
1001             return false;
1002         }
1003     } else return false;
1004 #endif
1005     if(m_framecounter > (int)m_period) {
1006      return true;
1007     }
1008
1009 }
1010
1011 void AmdtpReceiveStreamProcessor::setVerboseLevel(int l) {
1012         setDebugLevel(l);
1013         ReceiveStreamProcessor::setVerboseLevel(l);
1014
1015 }
1016
1017
1018 bool AmdtpReceiveStreamProcessor::reset() {
1019
1020         debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n");
1021
1022         // reset the event buffer, discard all content
1023         freebob_ringbuffer_reset(m_event_buffer);
1024        
1025         // reset the last timestamp
1026         m_last_timestamp=0;
1027        
1028         m_PeriodStat.reset();
1029     m_PacketStat.reset();
1030     m_WakeupStat.reset();
1031
1032        
1033         // reset all non-device specific stuff
1034         // i.e. the iso stream and the associated ports
1035         if(!ReceiveStreamProcessor::reset()) {
1036                 debugFatal("Could not do base class reset\n");
1037                 return false;
1038         }
1039         return true;
1040 }
1041
1042 bool AmdtpReceiveStreamProcessor::prepare() {
1043
1044     m_PeriodStat.setName("RCV PERIOD");
1045     m_PacketStat.setName("RCV PACKET");
1046     m_WakeupStat.setName("RCV WAKEUP");
1047
1048         // prepare all non-device specific stuff
1049         // i.e. the iso stream and the associated ports
1050         if(!ReceiveStreamProcessor::prepare()) {
1051                 debugFatal("Could not prepare base class\n");
1052                 return false;
1053         }
1054        
1055         debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing...\n");
1056         switch (m_framerate) {
1057         case 32000:
1058                 m_syt_interval = 8;
1059                 break;
1060         case 44100:
1061                 m_syt_interval = 8;
1062                 break;
1063         default:
1064         case 48000:
1065                 m_syt_interval = 8;
1066                 break;
1067         case 88200:
1068                 m_syt_interval = 16;
1069                 break;
1070         case 96000:
1071                 m_syt_interval = 16;
1072                 break;
1073         case 176400:
1074                 m_syt_interval = 32;
1075                 break;
1076         case 192000:
1077                 m_syt_interval = 32;
1078                 break;
1079         }
1080
1081     // allocate the event buffer
1082     unsigned int ringbuffer_size_frames=m_nb_buffers * m_period;
1083    
1084     // add the processing delay
1085     debugOutput(DEBUG_LEVEL_VERBOSE,"Adding %u frames of SYT slack buffering...\n",(m_framerate * RECEIVE_PROCESSING_DELAY)/TICKS_PER_SECOND);
1086     ringbuffer_size_frames+=(m_framerate * RECEIVE_PROCESSING_DELAY)/TICKS_PER_SECOND;
1087    
1088     if( !(m_event_buffer=freebob_ringbuffer_create(
1089             (m_dimension * ringbuffer_size_frames) * sizeof(quadlet_t)))) {
1090                 debugFatal("Could not allocate memory event ringbuffer");
1091 //              return -ENOMEM;
1092                 return false;
1093         }
1094
1095         // allocate the temporary cluster buffer
1096         if( !(m_cluster_buffer=(char *)calloc(m_dimension,sizeof(quadlet_t)))) {
1097                 debugFatal("Could not allocate temporary cluster buffer");
1098                 freebob_ringbuffer_free(m_event_buffer);
1099 //              return -ENOMEM;
1100                 return false;
1101         }
1102
1103         // set the parameters of ports we can:
1104         // we want the audio ports to be period buffered,
1105         // and the midi ports to be packet buffered
1106         for ( PortVectorIterator it = m_Ports.begin();
1107                   it != m_Ports.end();
1108                   ++it )
1109         {
1110                 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
1111                 if(!(*it)->setBufferSize(m_period)) {
1112                         debugFatal("Could not set buffer size to %d\n",m_period);
1113                         return false;
1114                 }
1115
1116                 switch ((*it)->getPortType()) {
1117                         case Port::E_Audio:
1118                                 if(!(*it)->setSignalType(Port::E_PeriodSignalled)) {
1119                                         debugFatal("Could not set signal type to PeriodSignalling");
1120                                         return false;
1121                                 }
1122                                 // buffertype and datatype are dependant on the API
1123                                 debugWarning("---------------- ! Doing hardcoded dummy setup ! --------------\n");
1124                                 // buffertype and datatype are dependant on the API
1125                                 if(!(*it)->setBufferType(Port::E_PointerBuffer)) {
1126                                         debugFatal("Could not set buffer type");
1127                                         return false;
1128                                 }
1129                                 if(!(*it)->useExternalBuffer(true)) {
1130                                         debugFatal("Could not set external buffer usage");
1131                                         return false;
1132                                 }
1133                                 if(!(*it)->setDataType(Port::E_Float)) {
1134                                         debugFatal("Could not set data type");
1135                                         return false;
1136                                 }
1137                                 break;
1138                         case Port::E_Midi:
1139                                 if(!(*it)->setSignalType(Port::E_PacketSignalled)) {
1140                                         debugFatal("Could not set signal type to PacketSignalling");
1141                                         return false;
1142                                 }
1143                                 // buffertype and datatype are dependant on the API
1144                                 // buffertype and datatype are dependant on the API
1145                                 debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n");
1146                                 // buffertype and datatype are dependant on the API
1147                                 if(!(*it)->setBufferType(Port::E_RingBuffer)) {
1148                                         debugFatal("Could not set buffer type");
1149                                         return false;
1150                                 }
1151                                 if(!(*it)->setDataType(Port::E_MidiEvent)) {
1152                                         debugFatal("Could not set data type");
1153                                         return false;
1154                                 }
1155                                 break;
1156                         default:
1157                                 debugWarning("Unsupported port type specified\n");
1158                                 break;
1159                 }
1160
1161         }
1162
1163         // the API specific settings of the ports should already be set,
1164         // as this is called from the processorManager->prepare()
1165         // so we can init the ports
1166         if(!initPorts()) {
1167                 debugFatal("Could not initialize ports!\n");
1168                 return false;
1169         }
1170
1171         if(!preparePorts()) {
1172                 debugFatal("Could not initialize ports!\n");
1173                 return false;
1174         }
1175
1176
1177         debugOutput( DEBUG_LEVEL_VERBOSE, "Prepared for:\n");
1178         debugOutput( DEBUG_LEVEL_VERBOSE, " Samplerate: %d, DBS: %d, SYT: %d\n",
1179                      m_framerate,m_dimension,m_syt_interval);
1180         debugOutput( DEBUG_LEVEL_VERBOSE, " PeriodSize: %d, NbBuffers: %d\n",
1181                      m_period,m_nb_buffers);
1182         debugOutput( DEBUG_LEVEL_VERBOSE, " Port: %d, Channel: %d\n",
1183                      m_port,m_channel);
1184         return true;
1185
1186 }
1187
1188 bool AmdtpReceiveStreamProcessor::transfer() {
1189
1190     m_PeriodStat.mark(freebob_ringbuffer_read_space(m_event_buffer)/(4*m_dimension));
1191
1192         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n");
1193        
1194 /* another naive section:       
1195         unsigned int read_size=m_period*sizeof(quadlet_t)*m_dimension;
1196         char *dummybuffer=(char *)calloc(sizeof(quadlet_t),m_period*m_dimension);
1197         if (freebob_ringbuffer_read(m_event_buffer,(char *)(dummybuffer),read_size) < read_size) {
1198                 debugWarning("Could not read from event buffer\n");
1199         }
1200
1201         receiveBlock(dummybuffer, m_period, 0);
1202
1203         free(dummybuffer);
1204 */
1205         int xrun;
1206         unsigned int offset=0;
1207        
1208         freebob_ringbuffer_data_t vec[2];
1209         // we received one period of frames on each connection
1210         // this is period_size*dimension of events
1211
1212         int events2read=m_period*m_dimension;
1213         int bytes2read=events2read*sizeof(quadlet_t);
1214         /* read events2read bytes from the ringbuffer
1215         *  first see if it can be done in one read.
1216         *  if so, ok.
1217         *  otherwise read up to a multiple of clusters directly from the buffer
1218         *  then do the buffer wrap around using ringbuffer_read
1219         *  then read the remaining data directly from the buffer in a third pass
1220         *  Make sure that we cannot end up on a non-cluster aligned position!
1221         */
1222         int cluster_size=m_dimension*sizeof(quadlet_t);
1223        
1224         while(bytes2read>0) {
1225                 unsigned int framesread=(m_period*cluster_size-bytes2read)/cluster_size;
1226                 offset=framesread;
1227                
1228                 int bytesread=0;
1229
1230                 freebob_ringbuffer_get_read_vector(m_event_buffer, vec);
1231                        
1232                 if(vec[0].len==0) { // this indicates an empty event buffer
1233                         debugError("RCV: Event buffer underrun in processor %p\n",this);
1234                         break;
1235                 }
1236                        
1237                 /* if we don't take care we will get stuck in an infinite loop
1238                 * because we align to a cluster boundary later
1239                 * the remaining nb of bytes in one read operation can be smaller than one cluster
1240                 * this can happen because the ringbuffer size is always a power of 2
1241                         */
1242                 if(vec[0].len<cluster_size) {
1243                         // use the ringbuffer function to read one cluster
1244                         // the read function handles wrap around
1245                         freebob_ringbuffer_read(m_event_buffer,m_cluster_buffer,cluster_size);
1246
1247                         xrun = receiveBlock(m_cluster_buffer, 1, offset);
1248                                
1249                         if(xrun<0) {
1250                                 // xrun detected
1251                                 debugError("RCV: Frame buffer overrun in processor %p\n",this);
1252                                 break;
1253                         }
1254                                
1255                                 // we advanced one cluster_size
1256                         bytes2read-=cluster_size;
1257                                
1258                 } else { //
1259                        
1260                         if(bytes2read>vec[0].len) {
1261                                         // align to a cluster boundary
1262                                 bytesread=vec[0].len-(vec[0].len%cluster_size);
1263                         } else {
1264                                 bytesread=bytes2read;
1265                         }
1266                                
1267                         xrun = receiveBlock(vec[0].buf, bytesread/cluster_size, offset);
1268                                
1269                         if(xrun<0) {
1270                                         // xrun detected
1271                                 debugError("RCV: Frame buffer overrun in processor %p\n",this);
1272                                 break;
1273                         }
1274
1275                         freebob_ringbuffer_read_advance(m_event_buffer, bytesread);
1276                         bytes2read -= bytesread;
1277                 }
1278                        
1279                 // the bytes2read should always be cluster aligned
1280                 assert(bytes2read%cluster_size==0);
1281         }
1282
1283         return true;
1284 }
1285
1286 /**
1287  * \brief write received events to the stream ringbuffers.
1288  */
1289 int AmdtpReceiveStreamProcessor::receiveBlock(char *data,
1290                                            unsigned int nevents, unsigned int offset)
1291 {
1292         int problem=0;
1293
1294         for ( PortVectorIterator it = m_PeriodPorts.begin();
1295           it != m_PeriodPorts.end();
1296           ++it )
1297     {
1298
1299         if((*it)->isDisabled()) {continue;};
1300
1301                 //FIXME: make this into a static_cast when not DEBUG?
1302
1303                 AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
1304                 assert(pinfo); // this should not fail!!
1305
1306                 switch(pinfo->getFormat()) {
1307                 case AmdtpPortInfo::E_MBLA:
1308                         if(decodeMBLAEventsToPort(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
1309                                 debugWarning("Could not decode packet MBLA to port %s",(*it)->getName().c_str());
1310                                 problem=1;
1311                         }
1312                         break;
1313                 case AmdtpPortInfo::E_SPDIF: // still unimplemented
1314                         break;
1315         /* for this processor, midi is a packet based port
1316                 case AmdtpPortInfo::E_Midi:
1317                         break;*/
1318                 default: // ignore
1319                         break;
1320                 }
1321     }
1322         return problem;
1323
1324 }
1325
1326 /**
1327  * @brief decode a packet for the packet-based ports
1328  *
1329  * @param data Packet data
1330  * @param nevents number of events in data (including events of other ports & port types)
1331  * @param dbc DataBlockCount value for this packet
1332  * @return true if all successfull
1333  */
1334 bool AmdtpReceiveStreamProcessor::decodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc)
1335 {
1336         bool ok=true;
1337        
1338         quadlet_t *target_event=NULL;
1339         int j;
1340        
1341         for ( PortVectorIterator it = m_PacketPorts.begin();
1342           it != m_PacketPorts.end();
1343           ++it )
1344         {
1345
1346 #ifdef DEBUG
1347                 AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
1348                 assert(pinfo); // this should not fail!!
1349
1350                 // the only packet type of events for AMDTP is MIDI in mbla
1351                 assert(pinfo->getFormat()==AmdtpPortInfo::E_Midi);
1352 #endif
1353                 AmdtpMidiPort *mp=static_cast<AmdtpMidiPort *>(*it);
1354                
1355                 // we decode this directly (no function call) due to the high frequency
1356                 /* idea:
1357                 spec says: current_midi_port=(dbc+j)%8;
1358                 => if we start at (dbc+stream->location-1)%8 [due to location_min=1],
1359                 we'll start at the right event for the midi port.
1360                 => if we increment j with 8, we stay at the right event.
1361                 */
1362                 // FIXME: as we know in advance how big a packet is (syt_interval) we can
1363                 //        predict how much loops will be present here
1364                 for(j = (dbc & 0x07)+mp->getLocation()-1; j < nevents; j += 8) {
1365                         target_event=(quadlet_t *)(data + ((j * m_dimension) + mp->getPosition()));
1366                         quadlet_t sample_int=ntohl(*target_event);
1367                         // FIXME: this assumes that 2X and 3X speed isn't used,
1368                         // because only the 1X slot is put into the ringbuffer
1369                         if(IEC61883_AM824_GET_LABEL(sample_int) != IEC61883_AM824_LABEL_MIDI_NO_DATA) {
1370                                 sample_int=(sample_int >> 16) & 0x000000FF;
1371                                 if(!mp->writeEvent(&sample_int)) {
1372                                         debugWarning("Packet port events lost\n");
1373                                         ok=false;
1374                                 }
1375                         }
1376                 }
1377
1378         }
1379        
1380         return ok;
1381 }
1382
1383 int AmdtpReceiveStreamProcessor::decodeMBLAEventsToPort(AmdtpAudioPort *p, quadlet_t *data,
1384                                            unsigned int offset, unsigned int nevents)
1385 {
1386         unsigned int j=0;
1387
1388 //      printf("****************\n");
1389 //      hexDumpQuadlets(data,m_dimension*4);
1390 //      printf("****************\n");
1391
1392         quadlet_t *target_event;
1393
1394         target_event=(quadlet_t *)(data + p->getPosition());
1395
1396         switch(p->getDataType()) {
1397                 default:
1398                 case Port::E_Int24:
1399                         {
1400                                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
1401
1402                                 assert(nevents + offset <= p->getBufferSize());
1403
1404                                 buffer+=offset;
1405
1406                                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
1407                                         *(buffer)=(ntohl((*target_event) ) & 0x00FFFFFF);
1408                                         buffer++;
1409                                         target_event+=m_dimension;
1410                                 }
1411                         }
1412                         break;
1413                 case Port::E_Float:
1414                         {
1415                                 const float multiplier = 1.0f / (float)(0x7FFFFF);
1416                                 float *buffer=(float *)(p->getBufferAddress());
1417
1418                                 assert(nevents + offset <= p->getBufferSize());
1419
1420                                 buffer+=offset;
1421
1422                                 for(j = 0; j < nevents; j += 1) { // decode max nsamples               
1423        
1424                                         unsigned int v = ntohl(*target_event) & 0x00FFFFFF;
1425                                         // sign-extend highest bit of 24-bit int
1426                                         int tmp = (int)(v << 8) / 256;
1427                
1428                                         *buffer = tmp * multiplier;
1429                                
1430                                         buffer++;
1431                                         target_event+=m_dimension;
1432                                 }
1433                         }
1434                         break;
1435         }
1436
1437         return 0;
1438 }
1439
1440 } // end of namespace FreebobStreaming
Note: See TracBrowser for help on using the browser.