root/branches/streaming-rework/src/libstreaming/AmdtpStreamProcessor.cpp

Revision 407, 46.1 kB (checked in by pieterpalmers, 16 years ago)

- Changed the way the device class configure options are handled. Now they are handled in the makefiles instead of the source files. The only source file that still contains the #ifdef's is devicemanager.cpp, to conditionally include the device class include files and to conditionally probe the classes that might be supported.
- added a configure option to disable the compilation of the test programs in tests/
- cleaned up the ADMTP transmit streamprocessor. Now it sends silenced packets when in the disabled state, instead of no-data packets
- added a getNodeID() to ieee1394service
- made comments in ieee1394service.h doxygen compliant

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,2007 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 #include "AmdtpStreamProcessor.h"
29 #include "Port.h"
30 #include "AmdtpPort.h"
31
32 #include "cycletimer.h"
33
34 #include <netinet/in.h>
35 #include <assert.h>
36
37 // in ticks
38 #define TRANSMIT_TRANSFER_DELAY 9000U
39 // the number of cycles to send a packet in advance of it's timestamp
40 #define TRANSMIT_ADVANCE_CYCLES 1U
41
42 namespace FreebobStreaming {
43
44 IMPL_DEBUG_MODULE( AmdtpTransmitStreamProcessor, AmdtpTransmitStreamProcessor, DEBUG_LEVEL_NORMAL );
45 IMPL_DEBUG_MODULE( AmdtpReceiveStreamProcessor, AmdtpReceiveStreamProcessor, DEBUG_LEVEL_NORMAL );
46
47
48 /* transmit */
49 AmdtpTransmitStreamProcessor::AmdtpTransmitStreamProcessor(int port, int framerate, int dimension)
50         : TransmitStreamProcessor(port, framerate), m_dimension(dimension)
51         , m_last_timestamp(0), m_dbc(0), m_ringbuffer_size_frames(0)
52 {
53
54 }
55
56 AmdtpTransmitStreamProcessor::~AmdtpTransmitStreamProcessor() {
57
58 }
59
60 /**
61  * @return
62  */
63 bool AmdtpTransmitStreamProcessor::init() {
64
65         debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing (%p)...\n");
66         // call the parent init
67         // this has to be done before allocating the buffers,
68         // because this sets the buffersizes from the processormanager
69         if(!TransmitStreamProcessor::init()) {
70                 debugFatal("Could not do base class init (%p)\n",this);
71                 return false;
72         }
73        
74         return true;
75 }
76
77 void AmdtpTransmitStreamProcessor::setVerboseLevel(int l) {
78         setDebugLevel(l);
79         TransmitStreamProcessor::setVerboseLevel(l);
80 }
81
82 enum raw1394_iso_disposition
83 AmdtpTransmitStreamProcessor::getPacket(unsigned char *data, unsigned int *length,
84                       unsigned char *tag, unsigned char *sy,
85                       int cycle, unsigned int dropped, unsigned int max_length) {
86    
87     struct iec61883_packet *packet = (struct iec61883_packet *) data;
88    
89     m_last_cycle=cycle;
90    
91     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Xmit handler for cycle %d, (running=%d, enabled=%d,%d)\n",
92         cycle, m_running, m_disabled, m_is_disabled);
93    
94 #ifdef DEBUG
95     if(dropped>0) {
96         debugWarning("Dropped %d packets on cycle %d\n",dropped, cycle);
97     }
98 #endif
99    
100     // calculate & preset common values
101    
102     /* Our node ID can change after a bus reset, so it is best to fetch
103      * our node ID for each packet. */
104     packet->sid = getNodeId() & 0x3f;
105
106     packet->dbs = m_dimension;
107     packet->fn = 0;
108     packet->qpc = 0;
109     packet->sph = 0;
110     packet->reserved = 0;
111     packet->dbc = m_dbc;
112     packet->eoh1 = 2;
113     packet->fmt = IEC61883_FMT_AMDTP;
114    
115     *tag = IEC61883_TAG_WITH_CIP;
116     *sy = 0;
117    
118     // determine if we want to send a packet or not
119     // note that we can't use getCycleTimer directly here,
120     // because packets are queued in advance. This means that
121     // we the packet we are constructing will be sent out
122     // on 'cycle', not 'now'.
123     unsigned int ctr=m_handler->getCycleTimer();
124     int now_cycles = (int)CYCLE_TIMER_GET_CYCLES(ctr);
125    
126     // the difference between the cycle this
127     // packet is intended for and 'now'
128     int cycle_diff = substractCycles(cycle, now_cycles);
129    
130 #ifdef DEBUG
131     if(m_running && (cycle_diff < 0)) {
132         debugWarning("Requesting packet for cycle %04d which is in the past (now=%04dcy)\n",
133             cycle, now_cycles);
134     }
135 #endif
136
137     // as long as the cycle parameter is not in sync with
138     // the current time, the stream is considered not
139     // to be 'running'
140     // NOTE: this works only at startup
141     if (!m_running && cycle_diff >= 0 && cycle != -1) {
142             debugOutput(DEBUG_LEVEL_VERBOSE, "Xmit StreamProcessor %p started running at cycle %d\n",this, cycle);
143             m_running=true;
144     }
145    
146     uint64_t ts_head, fc;
147     if (!m_disabled && m_is_disabled) {
148         // this means that we are trying to enable
149         if ((unsigned int)cycle == m_cycle_to_enable_at) {
150             m_is_disabled=false;
151            
152             debugOutput(DEBUG_LEVEL_VERBOSE,"Enabling StreamProcessor %p at %u\n", this, cycle);
153            
154             // initialize the buffer head & tail
155             m_SyncSource->m_data_buffer->getBufferHeadTimestamp(&ts_head, &fc); // thread safe
156            
157             // the number of cycles the sync source lags (> 0)
158             // or leads (< 0)
159             int sync_lag_cycles=substractCycles(cycle, m_SyncSource->getLastCycle());
160            
161             // account for the cycle lag between sync SP and this SP
162             // the last update of the sync source's timestamps was sync_lag_cycles
163             // cycles before the cycle we are calculating the timestamp for.
164             // if we were to use one-frame buffers, you would expect the
165             // frame that is sent on cycle CT to have a timestamp T1.
166             // ts_head however is for cycle CT-sync_lag_cycles, and lies
167             // therefore sync_lag_cycles * TICKS_PER_CYCLE earlier than
168             // T1.
169             ts_head = addTicks(ts_head, sync_lag_cycles * TICKS_PER_CYCLE);
170            
171             m_data_buffer->setBufferHeadTimestamp(ts_head);
172            
173             #ifdef DEBUG
174             if ((unsigned int)m_data_buffer->getFrameCounter() != m_data_buffer->getBufferSize()) {
175                 debugWarning("m_data_buffer->getFrameCounter() != m_data_buffer->getBufferSize()\n");
176             }
177             #endif
178             debugOutput(DEBUG_LEVEL_VERBOSE,"XMIT TS SET: TS=%10lld, LAG=%03d, FC=%4d\n",
179                             ts_head, sync_lag_cycles, m_data_buffer->getFrameCounter());
180         } else {
181             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
182                         "will enable StreamProcessor %p at %u, now is %d\n",
183                         this, m_cycle_to_enable_at, cycle);
184         }
185     } else if (m_disabled && !m_is_disabled) {
186         // trying to disable
187         debugOutput(DEBUG_LEVEL_VERBOSE,"disabling StreamProcessor %p at %u\n",
188                     this, cycle);
189         m_is_disabled=true;
190     }
191    
192     // the base timestamp is the one of the next sample in the buffer
193     m_data_buffer->getBufferHeadTimestamp(&ts_head, &fc); // thread safe
194
195     // we send a packet some cycles in advance, to avoid the
196     // following situation:
197     // suppose we are only a few ticks away from
198     // the moment to send this packet. therefore we decide
199     // not to send the packet, but send it in the next cycle.
200     // This means that the next time point will be 3072 ticks
201     // later, making that the timestamp will be expired when the
202     // packet is sent, unless TRANSFER_DELAY > 3072.
203     // this means that we need at least one cycle of extra buffering.
204     uint64_t ticks_to_advance = TICKS_PER_CYCLE * TRANSMIT_ADVANCE_CYCLES;
205    
206     // if cycle lies cycle_diff cycles in the future, we should
207     // queue this packet cycle_diff * TICKS_PER_CYCLE earlier than
208     // we would if it were to be sent immediately.
209     ticks_to_advance += cycle_diff * TICKS_PER_CYCLE;
210
211     // determine the 'now' time in ticks
212     uint64_t cycle_timer=CYCLE_TIMER_TO_TICKS(ctr);
213    
214     // time until the packet is to be sent (if > 0: send packet)
215     int64_t until_next=substractTicks(ts_head, cycle_timer + ticks_to_advance);
216
217     // if until_next < 0 we should send a filled packet
218     // otherwise we should send a NO-DATA packet
219     if((until_next<0) && (m_running)) {
220         // add the transmit transfer delay to construct the playout time (=SYT timestamp)
221         uint64_t ts_packet=addTicks(ts_head, TRANSMIT_TRANSFER_DELAY);
222    
223         // if we are disabled, send a silent packet
224         // and advance the buffer head timestamp
225         if(m_is_disabled) {
226            
227             transmitSilenceBlock((char *)(data+8), m_syt_interval, 0);
228             m_dbc += fillDataPacketHeader(packet, length, ts_packet);
229            
230             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT SYNC: CY=%04u TSH=%011llu TSP=%011llu\n",
231                 cycle, ts_head, ts_packet);
232
233             // update the base timestamp
234             uint32_t ts_step=(uint32_t)((float)(m_syt_interval)
235                              *m_SyncSource->m_data_buffer->getRate());
236            
237             // the next buffer head timestamp
238             ts_head=addTicks(ts_head,ts_step);
239             m_data_buffer->setBufferHeadTimestamp(ts_head);
240            
241             // defer to make sure we get to be enabled asap
242             return RAW1394_ISO_DEFER;
243            
244         } else { // enabled & packet due, read from the buffer
245             if (m_data_buffer->readFrames(m_syt_interval, (char *)(data + 8))) {
246                 m_dbc += fillDataPacketHeader(packet, length, ts_packet);
247                
248                 // process all ports that should be handled on a per-packet base
249                 // this is MIDI for AMDTP (due to the need of DBC)
250                 if (!encodePacketPorts((quadlet_t *)(data+8), m_syt_interval, packet->dbc)) {
251                     debugWarning("Problem encoding Packet Ports\n");
252                 }
253                
254                 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT: CY=%04u TSH=%011llu TSP=%011llu\n",
255                     cycle, ts_head, ts_packet);
256                
257                 return RAW1394_ISO_OK;
258                
259             } else if (now_cycles<cycle) {
260                 // we can still postpone the queueing of the packets
261                 // because the ISO transmit packet buffer is not empty yet
262                 return RAW1394_ISO_AGAIN;
263                
264             } else { // there is no more data in the ringbuffer
265                 // compose a silent packet, we should always
266                 // send a valid packet
267                 transmitSilenceBlock((char *)(data+8), m_syt_interval, 0);
268                 m_dbc += fillDataPacketHeader(packet, length, ts_packet);
269            
270                 debugWarning("Transmit buffer underrun (now %d, queue %d, target %d)\n",
271                         now_cycles, cycle, TICKS_TO_CYCLES(ts_packet));
272                 // signal underrun
273                 m_xruns++;
274                 // disable the processing, will be re-enabled when
275                 // the xrun is handled
276                 m_disabled=true;
277                 m_is_disabled=true;
278                
279                 return RAW1394_ISO_DEFER;
280             }
281         }
282        
283     } else { // no packet due, send no-data packet
284         m_dbc += fillNoDataPacketHeader(packet, length);
285         return RAW1394_ISO_DEFER;
286     }
287    
288     // we shouldn't get here
289     return RAW1394_ISO_ERROR;
290
291 }
292
293 unsigned int AmdtpTransmitStreamProcessor::fillDataPacketHeader(
294         struct iec61883_packet *packet, unsigned int* length,
295         uint32_t ts) {
296    
297     packet->fdf = m_fdf;
298
299     // convert the timestamp to SYT format
300     uint16_t timestamp_SYT = TICKS_TO_SYT(ts);
301     packet->syt = ntohs(timestamp_SYT);
302    
303     *length = m_syt_interval*sizeof(quadlet_t)*m_dimension + 8;
304
305     return m_syt_interval;
306 }
307
308 unsigned int AmdtpTransmitStreamProcessor::fillNoDataPacketHeader(
309         struct iec61883_packet *packet, unsigned int* length) {
310    
311     // no-data packets have syt=0xFFFF
312     // and have the usual amount of events as dummy data (?)
313     packet->fdf = IEC61883_FDF_NODATA;
314     packet->syt = 0xffff;
315    
316     // FIXME: either make this a setting or choose
317     bool send_payload=true;
318     if(send_payload) {
319         // this means no-data packets with payload (DICE doesn't like that)
320         *length = 2*sizeof(quadlet_t) + m_syt_interval * m_dimension * sizeof(quadlet_t);
321         return m_syt_interval;
322     } else {
323         // dbc is not incremented
324         // this means no-data packets without payload
325         *length = 2*sizeof(quadlet_t);
326         return 0;
327     }
328 }
329
330 int AmdtpTransmitStreamProcessor::getMinimalSyncDelay() {
331     return 0;
332 }
333
334 bool AmdtpTransmitStreamProcessor::prefill() {
335
336     debugOutput( DEBUG_LEVEL_VERBOSE, "Prefill transmit buffers...\n");
337    
338     if(!transferSilence(m_ringbuffer_size_frames)) {
339         debugFatal("Could not prefill transmit stream\n");
340         return false;
341     }
342
343     return true;
344 }
345
346 bool AmdtpTransmitStreamProcessor::reset() {
347
348     debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n");
349
350     // reset the statistics
351     m_PeriodStat.reset();
352     m_PacketStat.reset();
353     m_WakeupStat.reset();
354    
355     // we have to make sure that the buffer HEAD timestamp
356     // lies in the future for every possible buffer fill case.
357     int offset=(int)(m_ringbuffer_size_frames*m_ticks_per_frame);
358    
359     // we can substract the delay as it introduces
360     // unnescessary delay
361     offset -= m_SyncSource->getSyncDelay();
362    
363     m_data_buffer->setTickOffset(offset);
364    
365     // reset all non-device specific stuff
366     // i.e. the iso stream and the associated ports
367     if(!TransmitStreamProcessor::reset()) {
368         debugFatal("Could not do base class reset\n");
369         return false;
370     }
371    
372     // we should prefill the event buffer
373     if (!prefill()) {
374         debugFatal("Could not prefill buffers\n");
375         return false;   
376     }
377    
378     return true;
379 }
380
381 bool AmdtpTransmitStreamProcessor::prepare() {
382     m_PeriodStat.setName("XMT PERIOD");
383     m_PacketStat.setName("XMT PACKET");
384     m_WakeupStat.setName("XMT WAKEUP");
385
386     debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing (%p)...\n", this);
387    
388     // prepare all non-device specific stuff
389     // i.e. the iso stream and the associated ports
390     if(!TransmitStreamProcessor::prepare()) {
391         debugFatal("Could not prepare base class\n");
392         return false;
393     }
394    
395     switch (m_framerate) {
396     case 32000:
397         m_syt_interval = 8;
398         m_fdf = IEC61883_FDF_SFC_32KHZ;
399         break;
400     case 44100:
401         m_syt_interval = 8;
402         m_fdf = IEC61883_FDF_SFC_44K1HZ;
403         break;
404     default:
405     case 48000:
406         m_syt_interval = 8;
407         m_fdf = IEC61883_FDF_SFC_48KHZ;
408         break;
409     case 88200:
410         m_syt_interval = 16;
411         m_fdf = IEC61883_FDF_SFC_88K2HZ;
412         break;
413     case 96000:
414         m_syt_interval = 16;
415         m_fdf = IEC61883_FDF_SFC_96KHZ;
416         break;
417     case 176400:
418         m_syt_interval = 32;
419         m_fdf = IEC61883_FDF_SFC_176K4HZ;
420         break;
421     case 192000:
422         m_syt_interval = 32;
423         m_fdf = IEC61883_FDF_SFC_192KHZ;
424         break;
425     }
426    
427     iec61883_cip_init (
428         &m_cip_status,
429         IEC61883_FMT_AMDTP,
430         m_fdf,
431         m_framerate,
432         m_dimension,
433         m_syt_interval);
434
435     // prepare the framerate estimate
436     m_ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_framerate);
437    
438         // initialize internal buffer
439     m_ringbuffer_size_frames=m_nb_buffers * m_period;
440
441     assert(m_data_buffer);   
442     m_data_buffer->setBufferSize(m_ringbuffer_size_frames);
443     m_data_buffer->setEventSize(sizeof(quadlet_t));
444     m_data_buffer->setEventsPerFrame(m_dimension);
445    
446     m_data_buffer->setUpdatePeriod(m_period);
447     m_data_buffer->setNominalRate(m_ticks_per_frame);
448    
449     m_data_buffer->setWrapValue(128L*TICKS_PER_SECOND);
450    
451     m_data_buffer->prepare();
452
453     // set the parameters of ports we can:
454     // we want the audio ports to be period buffered,
455     // and the midi ports to be packet buffered
456     for ( PortVectorIterator it = m_Ports.begin();
457           it != m_Ports.end();
458           ++it )
459     {
460         debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
461         if(!(*it)->setBufferSize(m_period)) {
462             debugFatal("Could not set buffer size to %d\n",m_period);
463             return false;
464         }
465        
466        
467         switch ((*it)->getPortType()) {
468             case Port::E_Audio:
469                 if(!(*it)->setSignalType(Port::E_PeriodSignalled)) {
470                     debugFatal("Could not set signal type to PeriodSignalling");
471                     return false;
472                 }
473                 debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n");
474                 // buffertype and datatype are dependant on the API
475                 if(!(*it)->setBufferType(Port::E_PointerBuffer)) {
476                     debugFatal("Could not set buffer type");
477                     return false;
478                 }
479                 if(!(*it)->useExternalBuffer(true)) {
480                     debugFatal("Could not set external buffer usage");
481                     return false;
482                 }
483                
484                 if(!(*it)->setDataType(Port::E_Float)) {
485                     debugFatal("Could not set data type");
486                     return false;
487                 }
488                
489                
490                 break;
491             case Port::E_Midi:
492                 if(!(*it)->setSignalType(Port::E_PacketSignalled)) {
493                     debugFatal("Could not set signal type to PeriodSignalling");
494                     return false;
495                 }
496                
497                 // we use a timing unit of 10ns
498                 // this makes sure that for the max syt interval
499                 // we don't have rounding, and keeps the numbers low
500                 // we have 1 slot every 8 events
501                 // we have syt_interval events per packet
502                 // => syt_interval/8 slots per packet
503                 // packet rate is 8000pkt/sec => interval=125us
504                 // so the slot interval is (1/8000)/(syt_interval/8)
505                 // or: 1/(1000 * syt_interval) sec
506                 // which is 1e9/(1000*syt_interval) nsec
507                 // or 100000/syt_interval 'units'
508                 // the event interval is fixed to 320us = 32000 'units'
509                 if(!(*it)->useRateControl(true,(100000/m_syt_interval),32000, false)) {
510                     debugFatal("Could not set signal type to PeriodSignalling");
511                     return false;
512                 }
513                
514                 // buffertype and datatype are dependant on the API
515                 debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n");
516                 // buffertype and datatype are dependant on the API
517                 if(!(*it)->setBufferType(Port::E_RingBuffer)) {
518                     debugFatal("Could not set buffer type");
519                     return false;
520                 }
521                 if(!(*it)->setDataType(Port::E_MidiEvent)) {
522                     debugFatal("Could not set data type");
523                     return false;
524                 }
525                 break;
526             default:
527                 debugWarning("Unsupported port type specified\n");
528                 break;
529         }
530     }
531
532     // the API specific settings of the ports should already be set,
533     // as this is called from the processorManager->prepare()
534     // so we can init the ports
535     if(!initPorts()) {
536         debugFatal("Could not initialize ports!\n");
537         return false;
538     }
539
540     if(!preparePorts()) {
541         debugFatal("Could not initialize ports!\n");
542         return false;
543     }
544
545     debugOutput( DEBUG_LEVEL_VERBOSE, "Prepared for:\n");
546     debugOutput( DEBUG_LEVEL_VERBOSE, " Samplerate: %d, FDF: %d, DBS: %d, SYT: %d\n",
547              m_framerate,m_fdf,m_dimension,m_syt_interval);
548     debugOutput( DEBUG_LEVEL_VERBOSE, " PeriodSize: %d, NbBuffers: %d\n",
549              m_period,m_nb_buffers);
550     debugOutput( DEBUG_LEVEL_VERBOSE, " Port: %d, Channel: %d\n",
551              m_port,m_channel);
552
553     return true;
554
555 }
556
557 bool AmdtpTransmitStreamProcessor::prepareForStart() {
558
559     return true;
560 }
561
562 bool AmdtpTransmitStreamProcessor::prepareForStop() {
563     disable();
564     return true;
565 }
566
567 bool AmdtpTransmitStreamProcessor::prepareForEnable(uint64_t time_to_enable_at) {
568
569     debugOutput(DEBUG_LEVEL_VERBOSE,"Preparing to enable...\n");
570
571     // for the transmit SP, we have to initialize the
572     // buffer timestamp to something sane, because this timestamp
573     // is used when it is SyncSource
574    
575     // the time we initialize to will determine the time at which
576     // the first sample in the buffer will be sent, so we should
577     // make it at least 'time_to_enable_at'
578    
579     uint64_t now=m_handler->getCycleTimer();
580     unsigned int now_secs=CYCLE_TIMER_GET_SECS(now);
581    
582     // check if a wraparound on the secs will happen between
583     // now and the time we start
584     if (CYCLE_TIMER_GET_CYCLES(now)>time_to_enable_at) {
585         // the start will happen in the next second
586         now_secs++;
587         if (now_secs>=128) now_secs=0;
588     }
589    
590     uint64_t ts_head= now_secs*TICKS_PER_SECOND;
591     ts_head+=time_to_enable_at*TICKS_PER_CYCLE;
592    
593     // we also add the nb of cycles we transmit in advance
594     ts_head=addTicks(ts_head, TRANSMIT_ADVANCE_CYCLES*TICKS_PER_CYCLE);
595    
596     m_data_buffer->setBufferTailTimestamp(ts_head);
597
598
599     if (!StreamProcessor::prepareForEnable(time_to_enable_at)) {
600         debugError("StreamProcessor::prepareForEnable failed\n");
601         return false;
602     }
603
604     return true;
605 }
606
607 bool AmdtpTransmitStreamProcessor::transferSilence(unsigned int nframes) {
608     bool retval;
609    
610     char *dummybuffer=(char *)calloc(sizeof(quadlet_t),nframes*m_dimension);
611    
612     transmitSilenceBlock(dummybuffer, nframes, 0);
613
614     // add the silence data to the ringbuffer
615     if(m_data_buffer->writeFrames(nframes, dummybuffer, 0)) {
616         retval=true;
617     } else {
618         debugWarning("Could not write to event buffer\n");
619         retval=false;
620     }
621
622     free(dummybuffer);
623    
624     return retval;
625 }
626
627 bool AmdtpTransmitStreamProcessor::putFrames(unsigned int nbframes, int64_t ts) {
628     m_PeriodStat.mark(m_data_buffer->getBufferFill());
629    
630     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "AmdtpTransmitStreamProcessor::putFrames(%d, %llu)\n", nbframes, ts);
631    
632     // transfer the data
633     m_data_buffer->blockProcessWriteFrames(nbframes, ts);
634
635     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " New timestamp: %llu\n", ts);
636
637     return true;
638 }
639 /*
640  * write received events to the stream ringbuffers.
641  */
642
643 bool AmdtpTransmitStreamProcessor::processWriteBlock(char *data,
644                        unsigned int nevents, unsigned int offset)
645 {
646     bool no_problem=true;
647
648     for ( PortVectorIterator it = m_PeriodPorts.begin();
649           it != m_PeriodPorts.end();
650           ++it )
651     {
652
653         if((*it)->isDisabled()) {continue;};
654        
655         //FIXME: make this into a static_cast when not DEBUG?
656
657         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
658         assert(pinfo); // this should not fail!!
659
660         switch(pinfo->getFormat()) {
661         case AmdtpPortInfo::E_MBLA:
662             if(encodePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
663                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str());
664                 no_problem=false;
665             }
666             break;
667         case AmdtpPortInfo::E_SPDIF: // still unimplemented
668             break;
669         default: // ignore
670             break;
671         }
672     }
673     return no_problem;
674
675 }
676
677 int AmdtpTransmitStreamProcessor::transmitSilenceBlock(char *data,
678                        unsigned int nevents, unsigned int offset)
679 {
680     int problem=0;
681
682     for ( PortVectorIterator it = m_PeriodPorts.begin();
683           it != m_PeriodPorts.end();
684           ++it )
685     {
686
687         //FIXME: make this into a static_cast when not DEBUG?
688
689         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
690         assert(pinfo); // this should not fail!!
691
692         switch(pinfo->getFormat()) {
693         case AmdtpPortInfo::E_MBLA:
694             if(encodeSilencePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
695                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str());
696                 problem=1;
697             }
698             break;
699         case AmdtpPortInfo::E_SPDIF: // still unimplemented
700             break;
701         default: // ignore
702             break;
703         }
704     }
705     return problem;
706
707 }
708
709 /**
710  * @brief decode a packet for the packet-based ports
711  *
712  * @param data Packet data
713  * @param nevents number of events in data (including events of other ports & port types)
714  * @param dbc DataBlockCount value for this packet
715  * @return true if all successfull
716  */
717 bool AmdtpTransmitStreamProcessor::encodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc)
718 {
719     bool ok=true;
720     char byte;
721    
722     quadlet_t *target_event=NULL;
723     unsigned int j;
724    
725     for ( PortVectorIterator it = m_PacketPorts.begin();
726           it != m_PacketPorts.end();
727           ++it )
728     {
729
730 #ifdef DEBUG
731         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
732         assert(pinfo); // this should not fail!!
733
734         // the only packet type of events for AMDTP is MIDI in mbla
735         assert(pinfo->getFormat()==AmdtpPortInfo::E_Midi);
736 #endif
737        
738         AmdtpMidiPort *mp=static_cast<AmdtpMidiPort *>(*it);
739        
740         // we encode this directly (no function call) due to the high frequency
741         /* idea:
742         spec says: current_midi_port=(dbc+j)%8;
743         => if we start at (dbc+stream->location-1)%8 [due to location_min=1],
744         we'll start at the right event for the midi port.
745         => if we increment j with 8, we stay at the right event.
746         */
747         // FIXME: as we know in advance how big a packet is (syt_interval) we can
748         //        predict how much loops will be present here
749         // first prefill the buffer with NO_DATA's on all time muxed channels
750        
751         for(j = (dbc & 0x07)+mp->getLocation()-1; j < nevents; j += 8) {
752        
753             target_event=(quadlet_t *)(data + ((j * m_dimension) + mp->getPosition()));
754            
755             if(mp->canRead()) { // we can send a byte
756                 mp->readEvent(&byte);
757                 *target_event=htonl(
758                     IEC61883_AM824_SET_LABEL((byte)<<16,
759                                              IEC61883_AM824_LABEL_MIDI_1X));
760             } else {
761                 // can't send a byte, either because there is no byte,
762                 // or because this would exceed the maximum rate
763                 *target_event=htonl(
764                     IEC61883_AM824_SET_LABEL(0,IEC61883_AM824_LABEL_MIDI_NO_DATA));
765             }
766         }
767
768     }
769        
770     return ok;
771 }
772
773
774 int AmdtpTransmitStreamProcessor::encodePortToMBLAEvents(AmdtpAudioPort *p, quadlet_t *data,
775                        unsigned int offset, unsigned int nevents)
776 {
777     unsigned int j=0;
778
779     quadlet_t *target_event;
780
781     target_event=(quadlet_t *)(data + p->getPosition());
782
783     switch(p->getDataType()) {
784         default:
785         case Port::E_Int24:
786             {
787                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
788
789                 assert(nevents + offset <= p->getBufferSize());
790
791                 buffer+=offset;
792
793                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
794                     *target_event = htonl((*(buffer) & 0x00FFFFFF) | 0x40000000);
795                     buffer++;
796                     target_event += m_dimension;
797                 }
798             }
799             break;
800         case Port::E_Float:
801             {
802                 const float multiplier = (float)(0x7FFFFF00);
803                 float *buffer=(float *)(p->getBufferAddress());
804
805                 assert(nevents + offset <= p->getBufferSize());
806
807                 buffer+=offset;
808
809                 for(j = 0; j < nevents; j += 1) { // decode max nsamples               
810    
811                     // don't care for overflow
812                     float v = *buffer * multiplier;  // v: -231 .. 231
813                     unsigned int tmp = ((int)v);
814                     *target_event = htonl((tmp >> 8) | 0x40000000);
815                    
816                     buffer++;
817                     target_event += m_dimension;
818                 }
819             }
820             break;
821     }
822
823     return 0;
824 }
825 int AmdtpTransmitStreamProcessor::encodeSilencePortToMBLAEvents(AmdtpAudioPort *p, quadlet_t *data,
826                        unsigned int offset, unsigned int nevents)
827 {
828     unsigned int j=0;
829
830     quadlet_t *target_event;
831
832     target_event=(quadlet_t *)(data + p->getPosition());
833
834     switch(p->getDataType()) {
835         default:
836         case Port::E_Int24:
837         case Port::E_Float:
838             {
839                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
840                     *target_event = htonl(0x40000000);
841                     target_event += m_dimension;
842                 }
843             }
844             break;
845     }
846
847     return 0;
848 }
849
850 /* --------------------- RECEIVE ----------------------- */
851
852 AmdtpReceiveStreamProcessor::AmdtpReceiveStreamProcessor(int port, int framerate, int dimension)
853     : ReceiveStreamProcessor(port, framerate), m_dimension(dimension), m_last_timestamp(0), m_last_timestamp2(0) {
854
855 }
856
857 AmdtpReceiveStreamProcessor::~AmdtpReceiveStreamProcessor() {
858
859 }
860
861 bool AmdtpReceiveStreamProcessor::init() {
862
863     // call the parent init
864     // this has to be done before allocating the buffers,
865     // because this sets the buffersizes from the processormanager
866     if(!ReceiveStreamProcessor::init()) {
867         debugFatal("Could not do base class init (%d)\n",this);
868         return false;
869     }
870
871     return true;
872 }
873
874 enum raw1394_iso_disposition
875 AmdtpReceiveStreamProcessor::putPacket(unsigned char *data, unsigned int length,
876                   unsigned char channel, unsigned char tag, unsigned char sy,
877                   unsigned int cycle, unsigned int dropped) {
878    
879     enum raw1394_iso_disposition retval=RAW1394_ISO_OK;
880     m_last_cycle=cycle;
881    
882     struct iec61883_packet *packet = (struct iec61883_packet *) data;
883     assert(packet);
884
885 #ifdef DEBUG
886     if(dropped>0) {
887         debugWarning("Dropped %d packets on cycle %d\n",dropped, cycle);
888     }
889
890
891     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"ch%2u: CY=%4u, SYT=%08X (%4ucy + %04uticks) (running=%d, disabled=%d,%d)\n",
892         channel, cycle,ntohs(packet->syt), 
893         CYCLE_TIMER_GET_CYCLES(ntohs(packet->syt)), CYCLE_TIMER_GET_OFFSET(ntohs(packet->syt)),
894         m_running,m_disabled,m_is_disabled);
895
896     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
897         "RCV: CH = %d, FDF = %X. SYT = %6d, DBS = %3d, DBC = %3d, FMT = %3d, LEN = %4d\n",
898         channel, packet->fdf,
899         packet->syt,
900         packet->dbs,
901         packet->dbc,
902         packet->fmt,
903         length);
904
905 #endif
906     // check our enable status
907     if (!m_disabled && m_is_disabled) {
908         // this means that we are trying to enable
909         if (cycle == m_cycle_to_enable_at) {
910             m_is_disabled=false;
911             debugOutput(DEBUG_LEVEL_VERBOSE,"Enabling StreamProcessor %p at %d (SYT=%04X)\n",
912                 this, cycle, ntohs(packet->syt));
913             // the previous timestamp is the one we need to start with
914             // because we're going to update the buffer again this loop
915             // using writeframes
916             m_data_buffer->setBufferTailTimestamp(m_last_timestamp2);
917
918         } else {
919             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
920                 "will enable StreamProcessor %p at %u, now is %d\n",
921                     this, m_cycle_to_enable_at, cycle);
922         }
923     } else if (m_disabled && !m_is_disabled) {
924         // trying to disable
925         debugOutput(DEBUG_LEVEL_VERBOSE,"disabling StreamProcessor %p at %u\n", this, cycle);
926         m_is_disabled=true;
927     }
928
929     // check if this is a valid packet
930     if((packet->syt != 0xFFFF)
931        && (packet->fdf != 0xFF)
932        && (packet->fmt == 0x10)
933        && (packet->dbs>0)
934        && (length>=2*sizeof(quadlet_t))) {
935        
936         unsigned int nevents=((length / sizeof (quadlet_t)) - 2)/packet->dbs;
937
938         //=> store the previous timestamp
939         m_last_timestamp2=m_last_timestamp;
940
941         //=> convert the SYT to a full timestamp in ticks
942         m_last_timestamp=sytRecvToFullTicks((uint32_t)ntohs(packet->syt),
943                                         cycle, m_handler->getCycleTimer());
944
945         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "RECV: CY=%04u TS=%011llu\n",
946                 cycle, m_last_timestamp);
947        
948         // we have to keep in mind that there are also
949         // some packets buffered by the ISO layer,
950         // at most x=m_handler->getWakeupInterval()
951         // these contain at most x*syt_interval
952         // frames, meaning that we might receive
953         // this packet x*syt_interval*ticks_per_frame
954         // later than expected (the real receive time)
955         debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"STMP: %lluticks | buff=%d, syt_interval=%d, tpf=%f\n",
956             m_last_timestamp, m_handler->getWakeupInterval(),m_syt_interval,m_ticks_per_frame);
957        
958         //=> signal that we're running (if we are)
959         if(!m_running && nevents && m_last_timestamp2 && m_last_timestamp) {
960             debugOutput(DEBUG_LEVEL_VERBOSE,"Receive StreamProcessor %p started running at %d\n", this, cycle);
961             m_running=true;
962         }
963
964         //=> don't process the stream samples when it is not enabled.
965         if(m_is_disabled) {
966
967             // we keep track of the timestamp here
968             // this makes sure that we will have a somewhat accurate
969             // estimate as to when a period might be ready. i.e. it will not
970             // be ready earlier than this timestamp + period time
971            
972             // the next (possible) sample is not this one, but lies
973             // SYT_INTERVAL * rate later
974             uint64_t ts=addTicks(m_last_timestamp,
975                                  (uint64_t)((float)m_syt_interval * m_ticks_per_frame));
976
977             // set the timestamp as if there will be a sample put into
978             // the buffer by the next packet.
979             m_data_buffer->setBufferTailTimestamp(ts);
980            
981             return RAW1394_ISO_DEFER;
982         }
983        
984         #ifdef DEBUG_OFF
985         if((cycle % 1000) == 0) {
986             uint32_t syt = (uint32_t)ntohs(packet->syt);
987             uint32_t now=m_handler->getCycleTimer();
988             uint32_t now_ticks=CYCLE_TIMER_TO_TICKS(now);
989            
990             uint32_t test_ts=sytRecvToFullTicks(syt, cycle, now);
991
992             debugOutput(DEBUG_LEVEL_VERBOSE, "R %04d: SYT=%08X,            CY=%02d OFF=%04d\n",
993                 cycle, syt, CYCLE_TIMER_GET_CYCLES(syt), CYCLE_TIMER_GET_OFFSET(syt)
994                 );
995             debugOutput(DEBUG_LEVEL_VERBOSE, "R %04d: NOW=%011lu, SEC=%03u CY=%02u OFF=%04u\n",
996                 cycle, now_ticks, CYCLE_TIMER_GET_SECS(now), CYCLE_TIMER_GET_CYCLES(now), CYCLE_TIMER_GET_OFFSET(now)
997                 );
998             debugOutput(DEBUG_LEVEL_VERBOSE, "R %04d: TSS=%011lu, SEC=%03u CY=%02u OFF=%04u\n",
999                 cycle, test_ts, TICKS_TO_SECS(test_ts), TICKS_TO_CYCLES(test_ts), TICKS_TO_OFFSET(test_ts)
1000                 );
1001         }
1002         #endif
1003        
1004         //=> process the packet
1005         // add the data payload to the ringbuffer
1006         if(m_data_buffer->writeFrames(nevents, (char *)(data+8), m_last_timestamp)) {
1007             retval=RAW1394_ISO_OK;
1008            
1009             // process all ports that should be handled on a per-packet base
1010             // this is MIDI for AMDTP (due to the need of DBC)
1011             if (!decodePacketPorts((quadlet_t *)(data+8), nevents, packet->dbc)) {
1012                 debugWarning("Problem decoding Packet Ports\n");
1013                 retval=RAW1394_ISO_DEFER;
1014             }
1015            
1016         } else {
1017        
1018             debugWarning("Receive buffer overrun (cycle %d, FC=%d, PC=%d)\n",
1019                  cycle, m_data_buffer->getFrameCounter(), m_handler->getPacketCount());
1020            
1021             m_xruns++;
1022            
1023             // disable the processing, will be re-enabled when
1024             // the xrun is handled
1025             m_disabled=true;
1026             m_is_disabled=true;
1027
1028             retval=RAW1394_ISO_DEFER;
1029         }
1030     }
1031
1032     return retval;
1033 }
1034
1035 // returns the delay between the actual (real) time of a timestamp as received,
1036 // and the timestamp that is passed on for the same event. This is to cope with
1037 // ISO buffering
1038 int AmdtpReceiveStreamProcessor::getMinimalSyncDelay() {
1039     return ((int)(m_handler->getWakeupInterval() * m_syt_interval * m_ticks_per_frame)+10000);
1040 }
1041
1042 void AmdtpReceiveStreamProcessor::dumpInfo() {
1043     StreamProcessor::dumpInfo();
1044 }
1045
1046 void AmdtpReceiveStreamProcessor::setVerboseLevel(int l) {
1047         setDebugLevel(l);
1048         ReceiveStreamProcessor::setVerboseLevel(l);
1049 }
1050
1051 bool AmdtpReceiveStreamProcessor::reset() {
1052
1053     debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n");
1054
1055     m_PeriodStat.reset();
1056     m_PacketStat.reset();
1057     m_WakeupStat.reset();
1058    
1059     // this makes that the buffer lags a little compared to reality
1060     // the result is that we get some extra time before period boundaries
1061     // are signaled.
1062     // ISO buffering causes the packets to be received at max
1063     // m_handler->getWakeupInterval() later than the time they were received.
1064     // hence their payload is available this amount of time later. However, the
1065     // period boundary is predicted based upon earlier samples, and therefore can
1066     // pass before these packets are processed. Adding this extra term makes that
1067     // the period boundary is signalled later
1068     m_data_buffer->setTickOffset(m_SyncSource->getSyncDelay());
1069
1070     // reset all non-device specific stuff
1071     // i.e. the iso stream and the associated ports
1072     if(!ReceiveStreamProcessor::reset()) {
1073             debugFatal("Could not do base class reset\n");
1074             return false;
1075     }
1076     return true;
1077 }
1078
1079 bool AmdtpReceiveStreamProcessor::prepare() {
1080
1081     m_PeriodStat.setName("RCV PERIOD");
1082     m_PacketStat.setName("RCV PACKET");
1083     m_WakeupStat.setName("RCV WAKEUP");
1084
1085     debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing (%p)...\n", this);
1086        
1087         // prepare all non-device specific stuff
1088         // i.e. the iso stream and the associated ports
1089         if(!ReceiveStreamProcessor::prepare()) {
1090                 debugFatal("Could not prepare base class\n");
1091                 return false;
1092         }
1093        
1094         switch (m_framerate) {
1095         case 32000:
1096                 m_syt_interval = 8;
1097                 break;
1098         case 44100:
1099                 m_syt_interval = 8;
1100                 break;
1101         default:
1102         case 48000:
1103                 m_syt_interval = 8;
1104                 break;
1105         case 88200:
1106                 m_syt_interval = 16;
1107                 break;
1108         case 96000:
1109                 m_syt_interval = 16;
1110                 break;
1111         case 176400:
1112                 m_syt_interval = 32;
1113                 break;
1114         case 192000:
1115                 m_syt_interval = 32;
1116                 break;
1117         }
1118
1119     // prepare the framerate estimate
1120     m_ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_framerate);
1121
1122     debugOutput(DEBUG_LEVEL_VERBOSE,"Initializing remote ticks/frame to %f\n",m_ticks_per_frame);
1123
1124         // initialize internal buffer
1125     unsigned int ringbuffer_size_frames=m_nb_buffers * m_period;
1126    
1127     assert(m_data_buffer);   
1128     m_data_buffer->setBufferSize(ringbuffer_size_frames);
1129     m_data_buffer->setEventSize(sizeof(quadlet_t));
1130     m_data_buffer->setEventsPerFrame(m_dimension);
1131        
1132     // the buffer is written every syt_interval
1133     m_data_buffer->setUpdatePeriod(m_syt_interval);
1134     m_data_buffer->setNominalRate(m_ticks_per_frame);
1135    
1136     m_data_buffer->setWrapValue(128L*TICKS_PER_SECOND);
1137    
1138     m_data_buffer->prepare();
1139
1140         // set the parameters of ports we can:
1141         // we want the audio ports to be period buffered,
1142         // and the midi ports to be packet buffered
1143         for ( PortVectorIterator it = m_Ports.begin();
1144                   it != m_Ports.end();
1145                   ++it )
1146         {
1147                 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
1148                 if(!(*it)->setBufferSize(m_period)) {
1149                         debugFatal("Could not set buffer size to %d\n",m_period);
1150                         return false;
1151                 }
1152
1153                 switch ((*it)->getPortType()) {
1154                         case Port::E_Audio:
1155                                 if(!(*it)->setSignalType(Port::E_PeriodSignalled)) {
1156                                         debugFatal("Could not set signal type to PeriodSignalling");
1157                                         return false;
1158                                 }
1159                                 // buffertype and datatype are dependant on the API
1160                                 debugWarning("---------------- ! Doing hardcoded dummy setup ! --------------\n");
1161                                 // buffertype and datatype are dependant on the API
1162                                 if(!(*it)->setBufferType(Port::E_PointerBuffer)) {
1163                                         debugFatal("Could not set buffer type");
1164                                         return false;
1165                                 }
1166                                 if(!(*it)->useExternalBuffer(true)) {
1167                                         debugFatal("Could not set external buffer usage");
1168                                         return false;
1169                                 }
1170                                 if(!(*it)->setDataType(Port::E_Float)) {
1171                                         debugFatal("Could not set data type");
1172                                         return false;
1173                                 }
1174                                 break;
1175                         case Port::E_Midi:
1176                                 if(!(*it)->setSignalType(Port::E_PacketSignalled)) {
1177                                         debugFatal("Could not set signal type to PacketSignalling");
1178                                         return false;
1179                                 }
1180                                 // buffertype and datatype are dependant on the API
1181                                 // buffertype and datatype are dependant on the API
1182                                 debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n");
1183                                 // buffertype and datatype are dependant on the API
1184                                 if(!(*it)->setBufferType(Port::E_RingBuffer)) {
1185                                         debugFatal("Could not set buffer type");
1186                                         return false;
1187                                 }
1188                                 if(!(*it)->setDataType(Port::E_MidiEvent)) {
1189                                         debugFatal("Could not set data type");
1190                                         return false;
1191                                 }
1192                                 break;
1193                         default:
1194                                 debugWarning("Unsupported port type specified\n");
1195                                 break;
1196                 }
1197         }
1198
1199         // the API specific settings of the ports should already be set,
1200         // as this is called from the processorManager->prepare()
1201         // so we can init the ports
1202         if(!initPorts()) {
1203                 debugFatal("Could not initialize ports!\n");
1204                 return false;
1205         }
1206
1207         if(!preparePorts()) {
1208                 debugFatal("Could not initialize ports!\n");
1209                 return false;
1210         }
1211
1212
1213         debugOutput( DEBUG_LEVEL_VERBOSE, "Prepared for:\n");
1214         debugOutput( DEBUG_LEVEL_VERBOSE, " Samplerate: %d, DBS: %d, SYT: %d\n",
1215                      m_framerate,m_dimension,m_syt_interval);
1216         debugOutput( DEBUG_LEVEL_VERBOSE, " PeriodSize: %d, NbBuffers: %d\n",
1217                      m_period,m_nb_buffers);
1218         debugOutput( DEBUG_LEVEL_VERBOSE, " Port: %d, Channel: %d\n",
1219                      m_port,m_channel);
1220         return true;
1221
1222 }
1223
1224 bool AmdtpReceiveStreamProcessor::prepareForStart() {
1225     disable();
1226     return true;
1227 }
1228
1229 bool AmdtpReceiveStreamProcessor::prepareForStop() {
1230     disable();
1231     return true;
1232 }
1233
1234 bool AmdtpReceiveStreamProcessor::getFrames(unsigned int nbframes) {
1235
1236     m_PeriodStat.mark(m_data_buffer->getBufferFill());
1237
1238     // ask the buffer to process nbframes of frames
1239     // using it's registered client's processReadBlock(),
1240     // which should be ours
1241     m_data_buffer->blockProcessReadFrames(nbframes);
1242
1243     return true;
1244 }
1245
1246 /**
1247  * \brief write received events to the stream ringbuffers.
1248  */
1249 bool AmdtpReceiveStreamProcessor::processReadBlock(char *data,
1250                                            unsigned int nevents, unsigned int offset)
1251 {
1252         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "(%p)->processReadBlock(%u, %u)\n",this,nevents,offset);
1253        
1254         bool no_problem=true;
1255
1256         for ( PortVectorIterator it = m_PeriodPorts.begin();
1257           it != m_PeriodPorts.end();
1258           ++it )
1259     {
1260
1261         if((*it)->isDisabled()) {continue;};
1262
1263                 //FIXME: make this into a static_cast when not DEBUG?
1264
1265                 AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
1266                 assert(pinfo); // this should not fail!!
1267
1268                 switch(pinfo->getFormat()) {
1269                 case AmdtpPortInfo::E_MBLA:
1270                         if(decodeMBLAEventsToPort(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
1271                                 debugWarning("Could not decode packet MBLA to port %s",(*it)->getName().c_str());
1272                                 no_problem=false;
1273                         }
1274                         break;
1275                 case AmdtpPortInfo::E_SPDIF: // still unimplemented
1276                         break;
1277         /* for this processor, midi is a packet based port
1278                 case AmdtpPortInfo::E_Midi:
1279                         break;*/
1280                 default: // ignore
1281                         break;
1282                 }
1283     }
1284     return no_problem;
1285
1286 }
1287
1288 /**
1289  * @brief decode a packet for the packet-based ports
1290  *
1291  * @param data Packet data
1292  * @param nevents number of events in data (including events of other ports & port types)
1293  * @param dbc DataBlockCount value for this packet
1294  * @return true if all successfull
1295  */
1296 bool AmdtpReceiveStreamProcessor::decodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc)
1297 {
1298         bool ok=true;
1299        
1300         quadlet_t *target_event=NULL;
1301         unsigned int j;
1302        
1303         for ( PortVectorIterator it = m_PacketPorts.begin();
1304           it != m_PacketPorts.end();
1305           ++it )
1306         {
1307
1308 #ifdef DEBUG
1309                 AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
1310                 assert(pinfo); // this should not fail!!
1311
1312                 // the only packet type of events for AMDTP is MIDI in mbla
1313                 assert(pinfo->getFormat()==AmdtpPortInfo::E_Midi);
1314 #endif
1315                 AmdtpMidiPort *mp=static_cast<AmdtpMidiPort *>(*it);
1316                
1317                 // we decode this directly (no function call) due to the high frequency
1318                 /* idea:
1319                 spec says: current_midi_port=(dbc+j)%8;
1320                 => if we start at (dbc+stream->location-1)%8 [due to location_min=1],
1321                 we'll start at the right event for the midi port.
1322                 => if we increment j with 8, we stay at the right event.
1323                 */
1324                 // FIXME: as we know in advance how big a packet is (syt_interval) we can
1325                 //        predict how much loops will be present here
1326                 for(j = (dbc & 0x07)+mp->getLocation()-1; j < nevents; j += 8) {
1327                         target_event=(quadlet_t *)(data + ((j * m_dimension) + mp->getPosition()));
1328                         quadlet_t sample_int=ntohl(*target_event);
1329                         // FIXME: this assumes that 2X and 3X speed isn't used,
1330                         // because only the 1X slot is put into the ringbuffer
1331                         if(IEC61883_AM824_GET_LABEL(sample_int) != IEC61883_AM824_LABEL_MIDI_NO_DATA) {
1332                                 sample_int=(sample_int >> 16) & 0x000000FF;
1333                                 if(!mp->writeEvent(&sample_int)) {
1334                                         debugWarning("Packet port events lost\n");
1335                                         ok=false;
1336                                 }
1337                         }
1338                 }
1339
1340         }
1341        
1342         return ok;
1343 }
1344
1345 int AmdtpReceiveStreamProcessor::decodeMBLAEventsToPort(AmdtpAudioPort *p, quadlet_t *data,
1346                                            unsigned int offset, unsigned int nevents)
1347 {
1348         unsigned int j=0;
1349
1350 //      printf("****************\n");
1351 //      hexDumpQuadlets(data,m_dimension*4);
1352 //      printf("****************\n");
1353
1354         quadlet_t *target_event;
1355
1356         target_event=(quadlet_t *)(data + p->getPosition());
1357
1358         switch(p->getDataType()) {
1359                 default:
1360                 case Port::E_Int24:
1361                         {
1362                                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
1363
1364                                 assert(nevents + offset <= p->getBufferSize());
1365
1366                                 buffer+=offset;
1367
1368                                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
1369                                         *(buffer)=(ntohl((*target_event) ) & 0x00FFFFFF);
1370                                         buffer++;
1371                                         target_event+=m_dimension;
1372                                 }
1373                         }
1374                         break;
1375                 case Port::E_Float:
1376                         {
1377                                 const float multiplier = 1.0f / (float)(0x7FFFFF);
1378                                 float *buffer=(float *)(p->getBufferAddress());
1379
1380                                 assert(nevents + offset <= p->getBufferSize());
1381
1382                                 buffer+=offset;
1383
1384                                 for(j = 0; j < nevents; j += 1) { // decode max nsamples               
1385        
1386                                         unsigned int v = ntohl(*target_event) & 0x00FFFFFF;
1387                                         // sign-extend highest bit of 24-bit int
1388                                         int tmp = (int)(v << 8) / 256;
1389                
1390                                         *buffer = tmp * multiplier;
1391                                
1392                                         buffer++;
1393                                         target_event+=m_dimension;
1394                                 }
1395                         }
1396                         break;
1397         }
1398
1399         return 0;
1400 }
1401
1402 } // end of namespace FreebobStreaming
Note: See TracBrowser for help on using the browser.