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

Revision 401, 47.3 kB (checked in by pieterpalmers, 16 years ago)

move some code from amdtp SP to SP base class

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