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

Revision 707, 47.8 kB (checked in by ppalmers, 15 years ago)

- code cleanup
- make transmit handler AMDTP compliant (don't send too much in advance)

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 int AmdtpTransmitStreamProcessor::getMinimalSyncDelay() {
389     return 0;
390 }
391
392 bool AmdtpTransmitStreamProcessor::prefill() {
393
394     debugOutput( DEBUG_LEVEL_VERBOSE, "Prefill transmit buffers...\n");
395
396     if(!transferSilence(m_ringbuffer_size_frames)) {
397         debugFatal("Could not prefill transmit stream\n");
398         return false;
399     }
400
401     return true;
402 }
403
404 bool AmdtpTransmitStreamProcessor::reset() {
405
406     debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n");
407
408     // reset the statistics
409     m_PeriodStat.reset();
410     m_PacketStat.reset();
411     m_WakeupStat.reset();
412
413     m_data_buffer->setTickOffset(0);
414
415     // reset all non-device specific stuff
416     // i.e. the iso stream and the associated ports
417     if(!TransmitStreamProcessor::reset()) {
418         debugFatal("Could not do base class reset\n");
419         return false;
420     }
421
422     // we should prefill the event buffer
423     if (!prefill()) {
424         debugFatal("Could not prefill buffers\n");
425         return false;
426     }
427
428     return true;
429 }
430
431 bool AmdtpTransmitStreamProcessor::prepare() {
432     m_PeriodStat.setName("XMT PERIOD");
433     m_PacketStat.setName("XMT PACKET");
434     m_WakeupStat.setName("XMT WAKEUP");
435
436     debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing (%p)...\n", this);
437
438     // prepare all non-device specific stuff
439     // i.e. the iso stream and the associated ports
440     if(!TransmitStreamProcessor::prepare()) {
441         debugFatal("Could not prepare base class\n");
442         return false;
443     }
444
445     switch (m_framerate) {
446     case 32000:
447         m_syt_interval = 8;
448         m_fdf = IEC61883_FDF_SFC_32KHZ;
449         break;
450     case 44100:
451         m_syt_interval = 8;
452         m_fdf = IEC61883_FDF_SFC_44K1HZ;
453         break;
454     default:
455     case 48000:
456         m_syt_interval = 8;
457         m_fdf = IEC61883_FDF_SFC_48KHZ;
458         break;
459     case 88200:
460         m_syt_interval = 16;
461         m_fdf = IEC61883_FDF_SFC_88K2HZ;
462         break;
463     case 96000:
464         m_syt_interval = 16;
465         m_fdf = IEC61883_FDF_SFC_96KHZ;
466         break;
467     case 176400:
468         m_syt_interval = 32;
469         m_fdf = IEC61883_FDF_SFC_176K4HZ;
470         break;
471     case 192000:
472         m_syt_interval = 32;
473         m_fdf = IEC61883_FDF_SFC_192KHZ;
474         break;
475     }
476
477     iec61883_cip_init (
478         &m_cip_status,
479         IEC61883_FMT_AMDTP,
480         m_fdf,
481         m_framerate,
482         m_dimension,
483         m_syt_interval);
484
485     // prepare the framerate estimate
486     float ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_framerate);
487     m_ticks_per_frame=ticks_per_frame;
488
489     // initialize internal buffer
490     m_ringbuffer_size_frames=m_nb_buffers * m_period;
491
492     assert(m_data_buffer);
493     m_data_buffer->setBufferSize(m_ringbuffer_size_frames);
494     m_data_buffer->setEventSize(sizeof(quadlet_t));
495     m_data_buffer->setEventsPerFrame(m_dimension);
496
497     m_data_buffer->setUpdatePeriod(m_period);
498     m_data_buffer->setNominalRate(ticks_per_frame);
499
500     m_data_buffer->setWrapValue(128L*TICKS_PER_SECOND);
501
502     m_data_buffer->prepare();
503
504     // set the parameters of ports we can:
505     // we want the audio ports to be period buffered,
506     // and the midi ports to be packet buffered
507     for ( PortVectorIterator it = m_Ports.begin();
508           it != m_Ports.end();
509           ++it )
510     {
511         debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
512         if(!(*it)->setBufferSize(m_period)) {
513             debugFatal("Could not set buffer size to %d\n",m_period);
514             return false;
515         }
516
517
518         switch ((*it)->getPortType()) {
519             case Port::E_Audio:
520                 if(!(*it)->setSignalType(Port::E_PeriodSignalled)) {
521                     debugFatal("Could not set signal type to PeriodSignalling");
522                     return false;
523                 }
524                 debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n");
525                 // buffertype and datatype are dependant on the API
526                 if(!(*it)->setBufferType(Port::E_PointerBuffer)) {
527                     debugFatal("Could not set buffer type");
528                     return false;
529                 }
530                 if(!(*it)->useExternalBuffer(true)) {
531                     debugFatal("Could not set external buffer usage");
532                     return false;
533                 }
534
535                 if(!(*it)->setDataType(Port::E_Float)) {
536                     debugFatal("Could not set data type");
537                     return false;
538                 }
539
540
541                 break;
542             case Port::E_Midi:
543                 if(!(*it)->setSignalType(Port::E_PacketSignalled)) {
544                     debugFatal("Could not set signal type to PeriodSignalling");
545                     return false;
546                 }
547
548                 // we use a timing unit of 10ns
549                 // this makes sure that for the max syt interval
550                 // we don't have rounding, and keeps the numbers low
551                 // we have 1 slot every 8 events
552                 // we have syt_interval events per packet
553                 // => syt_interval/8 slots per packet
554                 // packet rate is 8000pkt/sec => interval=125us
555                 // so the slot interval is (1/8000)/(syt_interval/8)
556                 // or: 1/(1000 * syt_interval) sec
557                 // which is 1e9/(1000*syt_interval) nsec
558                 // or 100000/syt_interval 'units'
559                 // the event interval is fixed to 320us = 32000 'units'
560                 if(!(*it)->useRateControl(true,(100000/m_syt_interval),32000, false)) {
561                     debugFatal("Could not set signal type to PeriodSignalling");
562                     return false;
563                 }
564
565                 // buffertype and datatype are dependant on the API
566                 debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n");
567                 // buffertype and datatype are dependant on the API
568                 if(!(*it)->setBufferType(Port::E_RingBuffer)) {
569                     debugFatal("Could not set buffer type");
570                     return false;
571                 }
572                 if(!(*it)->setDataType(Port::E_MidiEvent)) {
573                     debugFatal("Could not set data type");
574                     return false;
575                 }
576                 break;
577             default:
578                 debugWarning("Unsupported port type specified\n");
579                 break;
580         }
581     }
582
583     // the API specific settings of the ports should already be set,
584     // as this is called from the processorManager->prepare()
585     // so we can init the ports
586     if(!initPorts()) {
587         debugFatal("Could not initialize ports!\n");
588         return false;
589     }
590
591     if(!preparePorts()) {
592         debugFatal("Could not initialize ports!\n");
593         return false;
594     }
595
596     debugOutput( DEBUG_LEVEL_VERBOSE, "Prepared for:\n");
597     debugOutput( DEBUG_LEVEL_VERBOSE, " Samplerate: %d, FDF: %d, DBS: %d, SYT: %d\n",
598              m_framerate,m_fdf,m_dimension,m_syt_interval);
599     debugOutput( DEBUG_LEVEL_VERBOSE, " PeriodSize: %d, NbBuffers: %d\n",
600              m_period,m_nb_buffers);
601     debugOutput( DEBUG_LEVEL_VERBOSE, " Port: %d, Channel: %d\n",
602              m_port,m_channel);
603
604     return true;
605
606 }
607
608 bool AmdtpTransmitStreamProcessor::prepareForStart() {
609     return true;
610 }
611
612 bool AmdtpTransmitStreamProcessor::prepareForStop() {
613     return true;
614 }
615
616 bool AmdtpTransmitStreamProcessor::prepareForEnable(uint64_t time_to_enable_at) {
617
618     if (!StreamProcessor::prepareForEnable(time_to_enable_at)) {
619         debugError("StreamProcessor::prepareForEnable failed\n");
620         return false;
621     }
622
623     return true;
624 }
625
626 bool AmdtpTransmitStreamProcessor::transferSilence(unsigned int nframes) {
627     bool retval;
628
629     char *dummybuffer=(char *)calloc(sizeof(quadlet_t),nframes*m_dimension);
630
631     transmitSilenceBlock(dummybuffer, nframes, 0);
632
633     // add the silence data to the ringbuffer
634     if(m_data_buffer->writeFrames(nframes, dummybuffer, 0)) {
635         retval=true;
636     } else {
637         debugWarning("Could not write to event buffer\n");
638         retval=false;
639     }
640
641     free(dummybuffer);
642
643     return retval;
644 }
645
646 bool AmdtpTransmitStreamProcessor::putFrames(unsigned int nbframes, int64_t ts) {
647     m_PeriodStat.mark(m_data_buffer->getBufferFill());
648     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "AmdtpTransmitStreamProcessor::putFrames(%d, %llu)\n", nbframes, ts);
649
650     // transfer the data
651     m_data_buffer->blockProcessWriteFrames(nbframes, ts);
652
653     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, " New timestamp: %llu\n", ts);
654
655     return true; // FIXME: what about failure?
656 }
657
658 bool AmdtpTransmitStreamProcessor::putFramesDry(unsigned int nbframes, int64_t ts) {
659     m_PeriodStat.mark(m_data_buffer->getBufferFill());
660     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "AmdtpTransmitStreamProcessor::putFramesDry(%d, %llu)\n", nbframes, ts);
661
662     bool retval;
663     char dummybuffer[sizeof(quadlet_t)*nbframes*m_dimension];
664
665     transmitSilenceBlock(dummybuffer, nbframes, 0);
666     // add the silence data to the ringbuffer
667     if(m_data_buffer->writeFrames(nbframes, dummybuffer, ts)) {
668         retval=true;
669     } else {
670         debugWarning("Could not write to event buffer\n");
671         retval=false;
672     }
673
674     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, " New timestamp: %llu\n", ts);
675     return retval;
676 }
677
678 /*
679  * write received events to the stream ringbuffers.
680  */
681
682 bool AmdtpTransmitStreamProcessor::processWriteBlock(char *data,
683                        unsigned int nevents, unsigned int offset)
684 {
685     bool no_problem=true;
686
687     for ( PortVectorIterator it = m_PeriodPorts.begin();
688           it != m_PeriodPorts.end();
689           ++it )
690     {
691
692         if((*it)->isDisabled()) {continue;};
693
694         //FIXME: make this into a static_cast when not DEBUG?
695
696         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
697         assert(pinfo); // this should not fail!!
698
699         switch(pinfo->getFormat()) {
700         case AmdtpPortInfo::E_MBLA:
701             if(encodePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
702                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str());
703                 no_problem=false;
704             }
705             break;
706         case AmdtpPortInfo::E_SPDIF: // still unimplemented
707             break;
708         default: // ignore
709             break;
710         }
711     }
712     return no_problem;
713
714 }
715
716 int AmdtpTransmitStreamProcessor::transmitSilenceBlock(char *data,
717                        unsigned int nevents, unsigned int offset)
718 {
719     int problem=0;
720
721     for ( PortVectorIterator it = m_PeriodPorts.begin();
722           it != m_PeriodPorts.end();
723           ++it )
724     {
725
726         //FIXME: make this into a static_cast when not DEBUG?
727
728         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
729         assert(pinfo); // this should not fail!!
730
731         switch(pinfo->getFormat()) {
732         case AmdtpPortInfo::E_MBLA:
733             if(encodeSilencePortToMBLAEvents(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
734                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str());
735                 problem=1;
736             }
737             break;
738         case AmdtpPortInfo::E_SPDIF: // still unimplemented
739             break;
740         default: // ignore
741             break;
742         }
743     }
744     return problem;
745
746 }
747
748 /**
749  * @brief decode a packet for the packet-based ports
750  *
751  * @param data Packet data
752  * @param nevents number of events in data (including events of other ports & port types)
753  * @param dbc DataBlockCount value for this packet
754  * @return true if all successfull
755  */
756 bool AmdtpTransmitStreamProcessor::encodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc)
757 {
758     bool ok=true;
759     quadlet_t byte;
760
761     quadlet_t *target_event=NULL;
762     unsigned int j;
763
764     for ( PortVectorIterator it = m_PacketPorts.begin();
765           it != m_PacketPorts.end();
766           ++it )
767     {
768
769 #ifdef DEBUG
770         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
771         assert(pinfo); // this should not fail!!
772
773         // the only packet type of events for AMDTP is MIDI in mbla
774         assert(pinfo->getFormat()==AmdtpPortInfo::E_Midi);
775 #endif
776
777         AmdtpMidiPort *mp=static_cast<AmdtpMidiPort *>(*it);
778
779         // we encode this directly (no function call) due to the high frequency
780         /* idea:
781         spec says: current_midi_port=(dbc+j)%8;
782         => if we start at (dbc+stream->location-1)%8,
783         we'll start at the right event for the midi port.
784         => if we increment j with 8, we stay at the right event.
785         */
786         // FIXME: as we know in advance how big a packet is (syt_interval) we can
787         //        predict how much loops will be present here
788         // first prefill the buffer with NO_DATA's on all time muxed channels
789
790         for(j = (dbc & 0x07)+mp->getLocation(); j < nevents; j += 8) {
791            
792             quadlet_t tmpval;
793            
794             target_event=(quadlet_t *)(data + ((j * m_dimension) + mp->getPosition()));
795            
796             if(mp->canRead()) { // we can send a byte
797                 mp->readEvent(&byte);
798                 byte &= 0xFF;
799                 tmpval=htonl(
800                     IEC61883_AM824_SET_LABEL((byte)<<16,
801                                              IEC61883_AM824_LABEL_MIDI_1X));
802
803                 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "MIDI port %s, pos=%d, loc=%d, dbc=%d, nevents=%d, dim=%d\n",
804                     mp->getName().c_str(), mp->getPosition(), mp->getLocation(), dbc, nevents, m_dimension);
805                 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "base=%p, target=%p, value=%08X\n",
806                     data, target_event, tmpval);
807                    
808             } else {
809                 // can't send a byte, either because there is no byte,
810                 // or because this would exceed the maximum rate
811                 tmpval=htonl(
812                     IEC61883_AM824_SET_LABEL(0,IEC61883_AM824_LABEL_MIDI_NO_DATA));
813             }
814            
815             *target_event=tmpval;
816         }
817
818     }
819
820     return ok;
821 }
822
823
824 int AmdtpTransmitStreamProcessor::encodePortToMBLAEvents(AmdtpAudioPort *p, quadlet_t *data,
825                        unsigned int offset, unsigned int nevents)
826 {
827     unsigned int j=0;
828
829     quadlet_t *target_event;
830
831     target_event=(quadlet_t *)(data + p->getPosition());
832
833     switch(p->getDataType()) {
834         default:
835         case Port::E_Int24:
836             {
837                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
838
839                 assert(nevents + offset <= p->getBufferSize());
840
841                 buffer+=offset;
842
843                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
844                     *target_event = htonl((*(buffer) & 0x00FFFFFF) | 0x40000000);
845                     buffer++;
846                     target_event += m_dimension;
847                 }
848             }
849             break;
850         case Port::E_Float:
851             {
852                 const float multiplier = (float)(0x7FFFFF00);
853                 float *buffer=(float *)(p->getBufferAddress());
854
855                 assert(nevents + offset <= p->getBufferSize());
856
857                 buffer+=offset;
858
859                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
860
861                     // don't care for overflow
862                     float v = *buffer * multiplier;  // v: -231 .. 231
863                     unsigned int tmp = ((int)v);
864                     *target_event = htonl((tmp >> 8) | 0x40000000);
865
866                     buffer++;
867                     target_event += m_dimension;
868                 }
869             }
870             break;
871     }
872
873     return 0;
874 }
875 int AmdtpTransmitStreamProcessor::encodeSilencePortToMBLAEvents(AmdtpAudioPort *p, quadlet_t *data,
876                        unsigned int offset, unsigned int nevents)
877 {
878     unsigned int j=0;
879
880     quadlet_t *target_event;
881
882     target_event=(quadlet_t *)(data + p->getPosition());
883
884     switch(p->getDataType()) {
885         default:
886         case Port::E_Int24:
887         case Port::E_Float:
888             {
889                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
890                     *target_event = htonl(0x40000000);
891                     target_event += m_dimension;
892                 }
893             }
894             break;
895     }
896
897     return 0;
898 }
899
900 /* --------------------- RECEIVE ----------------------- */
901
902 AmdtpReceiveStreamProcessor::AmdtpReceiveStreamProcessor(int port, int framerate, int dimension)
903     : ReceiveStreamProcessor(port, framerate), m_dimension(dimension), m_last_timestamp(0), m_last_timestamp2(0)
904 {}
905
906 bool AmdtpReceiveStreamProcessor::init() {
907
908     // call the parent init
909     // this has to be done before allocating the buffers,
910     // because this sets the buffersizes from the processormanager
911     if(!ReceiveStreamProcessor::init()) {
912         debugFatal("Could not do base class init (%d)\n",this);
913         return false;
914     }
915     return true;
916 }
917
918 enum raw1394_iso_disposition
919 AmdtpReceiveStreamProcessor::putPacket(unsigned char *data, unsigned int length,
920                   unsigned char channel, unsigned char tag, unsigned char sy,
921                   unsigned int cycle, unsigned int dropped) {
922
923     enum raw1394_iso_disposition retval=RAW1394_ISO_OK;
924     m_last_cycle=cycle;
925
926     struct iec61883_packet *packet = (struct iec61883_packet *) data;
927     assert(packet);
928
929 #ifdef DEBUG
930     if(dropped>0) {
931         debugWarning("Dropped %d packets on cycle %d\n",dropped, cycle);
932     }
933
934     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"ch%2u: CY=%4u, SYT=%08X (%4ucy + %04uticks) (running=%d)\n",
935         channel, cycle, ntohs(packet->syt),
936         CYCLE_TIMER_GET_CYCLES(ntohs(packet->syt)), CYCLE_TIMER_GET_OFFSET(ntohs(packet->syt)),
937         m_running);
938
939     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
940         "RCV: CH = %d, FDF = %X. SYT = %6d, DBS = %3d, DBC = %3d, FMT = %3d, LEN = %4d\n",
941         channel, packet->fdf,
942         packet->syt,
943         packet->dbs,
944         packet->dbc,
945         packet->fmt,
946         length);
947
948 #endif
949
950     // check if this is a valid packet
951     if((packet->syt != 0xFFFF)
952        && (packet->fdf != 0xFF)
953        && (packet->fmt == 0x10)
954        && (packet->dbs>0)
955        && (length>=2*sizeof(quadlet_t))) {
956
957         unsigned int nevents=((length / sizeof (quadlet_t)) - 2)/packet->dbs;
958
959         //=> store the previous timestamp
960         m_last_timestamp2=m_last_timestamp;
961
962         //=> convert the SYT to a full timestamp in ticks
963         m_last_timestamp=sytRecvToFullTicks((uint32_t)ntohs(packet->syt),
964                                         cycle, m_handler->getCycleTimer());
965
966         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "RECV: CY=%04u TS=%011llu\n",
967                 cycle, m_last_timestamp);
968
969         // we have to keep in mind that there are also
970         // some packets buffered by the ISO layer,
971         // at most x=m_handler->getWakeupInterval()
972         // these contain at most x*syt_interval
973         // frames, meaning that we might receive
974         // this packet x*syt_interval*ticks_per_frame
975         // later than expected (the real receive time)
976         debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"STMP: %lluticks | buff=%d, syt_interval=%d, tpf=%f\n",
977             m_last_timestamp, m_handler->getWakeupInterval(),m_syt_interval,getTicksPerFrame());
978
979         //=> signal that we're running (if we are)
980         if(!m_running && nevents && m_last_timestamp2 && m_last_timestamp) {
981             debugOutput(DEBUG_LEVEL_VERBOSE,"Receive StreamProcessor %p started running at %d\n", this, cycle);
982             m_running=true;
983         }
984
985         #ifdef DEBUG_OFF
986         if((cycle % 1000) == 0) {
987             uint32_t now=m_handler->getCycleTimer();
988             uint32_t syt = (uint32_t)ntohs(packet->syt);
989             uint32_t now_ticks=CYCLE_TIMER_TO_TICKS(now);
990
991             uint32_t test_ts=sytRecvToFullTicks(syt, cycle, now);
992
993             debugOutput(DEBUG_LEVEL_VERBOSE, "R %04d: SYT=%08X,            CY=%02d OFF=%04d\n",
994                 cycle, syt, CYCLE_TIMER_GET_CYCLES(syt), CYCLE_TIMER_GET_OFFSET(syt)
995                 );
996             debugOutput(DEBUG_LEVEL_VERBOSE, "R %04d: NOW=%011lu, SEC=%03u CY=%02u OFF=%04u\n",
997                 cycle, now_ticks, CYCLE_TIMER_GET_SECS(now), CYCLE_TIMER_GET_CYCLES(now), CYCLE_TIMER_GET_OFFSET(now)
998                 );
999             debugOutput(DEBUG_LEVEL_VERBOSE, "R %04d: TSS=%011lu, SEC=%03u CY=%02u OFF=%04u\n",
1000                 cycle, test_ts, TICKS_TO_SECS(test_ts), TICKS_TO_CYCLES(test_ts), TICKS_TO_OFFSET(test_ts)
1001                 );
1002         }
1003         #endif
1004
1005         #ifdef DEBUG
1006             // keep track of the lag
1007             uint32_t now=m_handler->getCycleTimer();
1008             int32_t diff = diffCycles( cycle,  ((int)CYCLE_TIMER_GET_CYCLES(now)) );
1009             m_PacketStat.mark(diff);
1010         #endif
1011
1012         //=> process the packet
1013         // add the data payload to the ringbuffer
1014         if(m_data_buffer->writeFrames(nevents, (char *)(data+8), m_last_timestamp)) {
1015             retval=RAW1394_ISO_OK;
1016
1017             // process all ports that should be handled on a per-packet base
1018             // this is MIDI for AMDTP (due to the need of DBC)
1019             if (!decodePacketPorts((quadlet_t *)(data+8), nevents, packet->dbc)) {
1020                 debugWarning("Problem decoding Packet Ports\n");
1021                 retval=RAW1394_ISO_DEFER;
1022             }
1023
1024         } else {
1025
1026 //             debugWarning("Receive buffer overrun (cycle %d, FC=%d, PC=%d)\n",
1027 //                  cycle, m_data_buffer->getFrameCounter(), m_handler->getPacketCount());
1028
1029             m_xruns++;
1030
1031             retval=RAW1394_ISO_DEFER;
1032         }
1033     }
1034
1035     return retval;
1036 }
1037
1038 // returns the delay between the actual (real) time of a timestamp as received,
1039 // and the timestamp that is passed on for the same event. This is to cope with
1040 // ISO buffering
1041 int AmdtpReceiveStreamProcessor::getMinimalSyncDelay() {
1042     return ((int)(m_handler->getWakeupInterval() * m_syt_interval * getTicksPerFrame()));
1043 }
1044
1045 void AmdtpReceiveStreamProcessor::dumpInfo() {
1046     StreamProcessor::dumpInfo();
1047 }
1048
1049 bool AmdtpReceiveStreamProcessor::reset() {
1050
1051     debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n");
1052
1053     m_PeriodStat.reset();
1054     m_PacketStat.reset();
1055     m_WakeupStat.reset();
1056
1057     m_data_buffer->setTickOffset(0);
1058
1059     // reset all non-device specific stuff
1060     // i.e. the iso stream and the associated ports
1061     if(!ReceiveStreamProcessor::reset()) {
1062             debugFatal("Could not do base class reset\n");
1063             return false;
1064     }
1065     return true;
1066 }
1067
1068 bool AmdtpReceiveStreamProcessor::prepare() {
1069
1070     m_PeriodStat.setName("RCV PERIOD");
1071     m_PacketStat.setName("RCV PACKET");
1072     m_WakeupStat.setName("RCV WAKEUP");
1073
1074     debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing (%p)...\n", this);
1075
1076     // prepare all non-device specific stuff
1077     // i.e. the iso stream and the associated ports
1078     if(!ReceiveStreamProcessor::prepare()) {
1079         debugFatal("Could not prepare base class\n");
1080         return false;
1081     }
1082
1083     switch (m_framerate) {
1084     case 32000:
1085         m_syt_interval = 8;
1086         break;
1087     case 44100:
1088         m_syt_interval = 8;
1089         break;
1090     default:
1091     case 48000:
1092         m_syt_interval = 8;
1093         break;
1094     case 88200:
1095         m_syt_interval = 16;
1096         break;
1097     case 96000:
1098         m_syt_interval = 16;
1099         break;
1100     case 176400:
1101         m_syt_interval = 32;
1102         break;
1103     case 192000:
1104         m_syt_interval = 32;
1105         break;
1106     }
1107
1108     // prepare the framerate estimate
1109     float ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_framerate);
1110     m_ticks_per_frame=ticks_per_frame;
1111
1112     debugOutput(DEBUG_LEVEL_VERBOSE,"Initializing remote ticks/frame to %f\n",ticks_per_frame);
1113
1114     // initialize internal buffer
1115     unsigned int ringbuffer_size_frames=m_nb_buffers * m_period;
1116
1117     assert(m_data_buffer);
1118     m_data_buffer->setBufferSize(ringbuffer_size_frames);
1119     m_data_buffer->setEventSize(sizeof(quadlet_t));
1120     m_data_buffer->setEventsPerFrame(m_dimension);
1121
1122     // the buffer is written every syt_interval
1123     m_data_buffer->setUpdatePeriod(m_syt_interval);
1124     m_data_buffer->setNominalRate(ticks_per_frame);
1125
1126     m_data_buffer->setWrapValue(128L*TICKS_PER_SECOND);
1127
1128     m_data_buffer->prepare();
1129
1130     // set the parameters of ports we can:
1131     // we want the audio ports to be period buffered,
1132     // and the midi ports to be packet buffered
1133     for ( PortVectorIterator it = m_Ports.begin();
1134           it != m_Ports.end();
1135           ++it )
1136     {
1137         debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
1138         if(!(*it)->setBufferSize(m_period)) {
1139             debugFatal("Could not set buffer size to %d\n",m_period);
1140             return false;
1141         }
1142
1143         switch ((*it)->getPortType()) {
1144             case Port::E_Audio:
1145                 if(!(*it)->setSignalType(Port::E_PeriodSignalled)) {
1146                     debugFatal("Could not set signal type to PeriodSignalling");
1147                     return false;
1148                 }
1149                 // buffertype and datatype are dependant on the API
1150                 debugWarning("---------------- ! Doing hardcoded dummy setup ! --------------\n");
1151                 // buffertype and datatype are dependant on the API
1152                 if(!(*it)->setBufferType(Port::E_PointerBuffer)) {
1153                     debugFatal("Could not set buffer type");
1154                     return false;
1155                 }
1156                 if(!(*it)->useExternalBuffer(true)) {
1157                     debugFatal("Could not set external buffer usage");
1158                     return false;
1159                 }
1160                 if(!(*it)->setDataType(Port::E_Float)) {
1161                     debugFatal("Could not set data type");
1162                     return false;
1163                 }
1164                 break;
1165             case Port::E_Midi:
1166                 if(!(*it)->setSignalType(Port::E_PacketSignalled)) {
1167                     debugFatal("Could not set signal type to PacketSignalling");
1168                     return false;
1169                 }
1170                 // buffertype and datatype are dependant on the API
1171                 // buffertype and datatype are dependant on the API
1172                 debugWarning("---------------- ! Doing hardcoded test setup ! --------------\n");
1173                 // buffertype and datatype are dependant on the API
1174                 if(!(*it)->setBufferType(Port::E_RingBuffer)) {
1175                     debugFatal("Could not set buffer type");
1176                     return false;
1177                 }
1178                 if(!(*it)->setDataType(Port::E_MidiEvent)) {
1179                     debugFatal("Could not set data type");
1180                     return false;
1181                 }
1182                 break;
1183             default:
1184                 debugWarning("Unsupported port type specified\n");
1185                 break;
1186         }
1187     }
1188
1189     // the API specific settings of the ports should already be set,
1190     // as this is called from the processorManager->prepare()
1191     // so we can init the ports
1192     if(!initPorts()) {
1193         debugFatal("Could not initialize ports!\n");
1194         return false;
1195     }
1196
1197     if(!preparePorts()) {
1198         debugFatal("Could not initialize ports!\n");
1199         return false;
1200     }
1201
1202     debugOutput( DEBUG_LEVEL_VERBOSE, "Prepared for:\n");
1203     debugOutput( DEBUG_LEVEL_VERBOSE, " Samplerate: %d, DBS: %d, SYT: %d\n",
1204              m_framerate,m_dimension,m_syt_interval);
1205     debugOutput( DEBUG_LEVEL_VERBOSE, " PeriodSize: %d, NbBuffers: %d\n",
1206              m_period,m_nb_buffers);
1207     debugOutput( DEBUG_LEVEL_VERBOSE, " Port: %d, Channel: %d\n",
1208              m_port,m_channel);
1209
1210     return true;
1211
1212 }
1213
1214 bool AmdtpReceiveStreamProcessor::prepareForStart() {
1215     disable();
1216     return true;
1217 }
1218
1219 bool AmdtpReceiveStreamProcessor::prepareForStop() {
1220     disable();
1221     return true;
1222 }
1223
1224 bool AmdtpReceiveStreamProcessor::getFrames(unsigned int nbframes, int64_t ts) {
1225     m_PeriodStat.mark(m_data_buffer->getBufferFill());
1226
1227     // ask the buffer to process nbframes of frames
1228     // using it's registered client's processReadBlock(),
1229     // which should be ours
1230     m_data_buffer->blockProcessReadFrames(nbframes);
1231
1232     return true;
1233 }
1234
1235 bool AmdtpReceiveStreamProcessor::getFramesDry(unsigned int nbframes, int64_t ts) {
1236     m_PeriodStat.mark(m_data_buffer->getBufferFill());
1237     int frames_to_ditch=(int)(nbframes);
1238     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "stream (%p): dry run %d frames (@ ts=%lld)\n",
1239                  this, frames_to_ditch, ts);
1240     char dummy[m_data_buffer->getBytesPerFrame()]; // one frame of garbage
1241
1242     while (frames_to_ditch--) {
1243         m_data_buffer->readFrames(1, dummy);
1244     }
1245     return true;
1246 }
1247
1248 /**
1249  * \brief write received events to the stream ringbuffers.
1250  */
1251 bool AmdtpReceiveStreamProcessor::processReadBlock(char *data,
1252                        unsigned int nevents, unsigned int offset)
1253 {
1254     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "(%p)->processReadBlock(%u, %u)\n",this,nevents,offset);
1255
1256     bool no_problem=true;
1257
1258     for ( PortVectorIterator it = m_PeriodPorts.begin();
1259           it != m_PeriodPorts.end();
1260           ++it )
1261     {
1262
1263         if((*it)->isDisabled()) {continue;};
1264
1265         //FIXME: make this into a static_cast when not DEBUG?
1266
1267         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
1268         assert(pinfo); // this should not fail!!
1269
1270         switch(pinfo->getFormat()) {
1271         case AmdtpPortInfo::E_MBLA:
1272             if(decodeMBLAEventsToPort(static_cast<AmdtpAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
1273                 debugWarning("Could not decode packet MBLA to port %s",(*it)->getName().c_str());
1274                 no_problem=false;
1275             }
1276             break;
1277         case AmdtpPortInfo::E_SPDIF: // still unimplemented
1278             break;
1279     /* for this processor, midi is a packet based port
1280         case AmdtpPortInfo::E_Midi:
1281             break;*/
1282         default: // ignore
1283             break;
1284         }
1285     }
1286     return no_problem;
1287
1288 }
1289
1290 /**
1291  * @brief decode a packet for the packet-based ports
1292  *
1293  * @param data Packet data
1294  * @param nevents number of events in data (including events of other ports & port types)
1295  * @param dbc DataBlockCount value for this packet
1296  * @return true if all successfull
1297  */
1298 bool AmdtpReceiveStreamProcessor::decodePacketPorts(quadlet_t *data, unsigned int nevents, unsigned int dbc)
1299 {
1300     bool ok=true;
1301
1302     quadlet_t *target_event=NULL;
1303     unsigned int j;
1304
1305     for ( PortVectorIterator it = m_PacketPorts.begin();
1306           it != m_PacketPorts.end();
1307           ++it )
1308     {
1309
1310 #ifdef DEBUG
1311         AmdtpPortInfo *pinfo=dynamic_cast<AmdtpPortInfo *>(*it);
1312         assert(pinfo); // this should not fail!!
1313
1314         // the only packet type of events for AMDTP is MIDI in mbla
1315         assert(pinfo->getFormat()==AmdtpPortInfo::E_Midi);
1316 #endif
1317         AmdtpMidiPort *mp=static_cast<AmdtpMidiPort *>(*it);
1318
1319         // we decode this directly (no function call) due to the high frequency
1320         /* idea:
1321         spec says: current_midi_port=(dbc+j)%8;
1322         => if we start at (dbc+stream->location-1)%8,
1323         we'll start at the right event for the midi port.
1324         => if we increment j with 8, we stay at the right event.
1325         */
1326         // FIXME: as we know in advance how big a packet is (syt_interval) we can
1327         //        predict how much loops will be present here
1328         for(j = (dbc & 0x07)+mp->getLocation(); j < nevents; j += 8) {
1329             target_event=(quadlet_t *)(data + ((j * m_dimension) + mp->getPosition()));
1330             quadlet_t sample_int=ntohl(*target_event);
1331             // FIXME: this assumes that 2X and 3X speed isn't used,
1332             // because only the 1X slot is put into the ringbuffer
1333             if(IEC61883_AM824_GET_LABEL(sample_int) != IEC61883_AM824_LABEL_MIDI_NO_DATA) {
1334                 sample_int=(sample_int >> 16) & 0x000000FF;
1335                 if(!mp->writeEvent(&sample_int)) {
1336                     debugWarning("Packet port events lost\n");
1337                     ok=false;
1338                 }
1339             }
1340         }
1341
1342     }
1343
1344     return ok;
1345 }
1346
1347 int AmdtpReceiveStreamProcessor::decodeMBLAEventsToPort(AmdtpAudioPort *p, quadlet_t *data,
1348                        unsigned int offset, unsigned int nevents)
1349 {
1350     unsigned int j=0;
1351
1352 //     printf("****************\n");
1353 //     hexDumpQuadlets(data,m_dimension*4);
1354 //     printf("****************\n");
1355
1356     quadlet_t *target_event;
1357
1358     target_event=(quadlet_t *)(data + p->getPosition());
1359
1360     switch(p->getDataType()) {
1361         default:
1362         case Port::E_Int24:
1363             {
1364                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
1365
1366                 assert(nevents + offset <= p->getBufferSize());
1367
1368                 buffer+=offset;
1369
1370                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
1371                     *(buffer)=(ntohl((*target_event) ) & 0x00FFFFFF);
1372                     buffer++;
1373                     target_event+=m_dimension;
1374                 }
1375             }
1376             break;
1377         case Port::E_Float:
1378             {
1379                 const float multiplier = 1.0f / (float)(0x7FFFFF);
1380                 float *buffer=(float *)(p->getBufferAddress());
1381
1382                 assert(nevents + offset <= p->getBufferSize());
1383
1384                 buffer+=offset;
1385
1386                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
1387
1388                     unsigned int v = ntohl(*target_event) & 0x00FFFFFF;
1389                     // sign-extend highest bit of 24-bit int
1390                     int tmp = (int)(v << 8) / 256;
1391
1392                     *buffer = tmp * multiplier;
1393
1394                     buffer++;
1395                     target_event+=m_dimension;
1396                 }
1397             }
1398             break;
1399     }
1400
1401     return 0;
1402 }
1403
1404 } // end of namespace Streaming
Note: See TracBrowser for help on using the browser.