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

Revision 709, 47.4 kB (checked in by ppalmers, 15 years ago)

some more streaming system updates.
this works with the saffire up till -n2 -p256

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