root/trunk/libffado/src/libstreaming/AmdtpStreamProcessor.cpp

Revision 494, 49.5 kB (checked in by ppalmers, 15 years ago)

- switch over to a generic ffado_timestamp_t for the timestamped buffer (currently float)
- implemented some experimental stream phase sync method

- various small things

NOTE: not a very stable commit

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