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

Revision 402, 46.6 kB (checked in by pieterpalmers, 16 years ago)

adapted the Motu SP to the new stream sync framework

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