root/branches/libffado-scons_porting_work/src/libstreaming/AmdtpStreamProcessor.cpp

Revision 547, 49.8 kB (checked in by arnonym, 15 years ago)

Port ppalmers fixes for spdif to this scons branch. This will affect nothing in the end, as the transition from scons-branch to trunk will involve only the build-system and (almost) no sources...

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