root/branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpStreamProcessor.cpp

Revision 705, 44.4 kB (checked in by ppalmers, 15 years ago)

restructure the streaming directory

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