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

Revision 261, 52.6 kB (checked in by pieterpalmers, 18 years ago)

- enabled verbose debugging for packet handlers in amdtp (PPC issues)
- fixed iec61883_packet struct to work on PPC.

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