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

Revision 404, 47.0 kB (checked in by pieterpalmers, 16 years ago)

- introduce support framework for DICE and Metric Halo
- change probe/discovery code to make adding devices easier
- made conditional compilation effectively work.

./configure now has the following switches:

--enable-bebob build BeBoB support (default=yes)
--enable-motu build Motu support (default=no)
--enable-dice build DICE support (default=no)
--enable-metric-halo build Metric Halo support (note: completely useless)

(default=no)

--enable-rme build RME support (note: completely useless)

(default=no)

--enable-bounce build Bounce device support (default=no)
--enable-all-devices build support for all supported devices (default=no)

these now turn on/off compilation effectively.

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