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

Revision 703, 44.4 kB (checked in by ppalmers, 16 years ago)

- rework of streaming startup
- started moving files around to enhance structure

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