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

Revision 397, 50.3 kB (checked in by pieterpalmers, 17 years ago)

- make timestampedbuffer use floats instead of doubles
- change iso receive back to the efficient case

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