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

Revision 424, 46.0 kB (checked in by pieterpalmers, 17 years ago)

- The library can now be started in 'slave mode', creating a BounceSlaveDevice?.

On a discovering node, this slave device is discovered as a BounceDevice?.
Streaming does not work yet, something wrong with the timestamps.

- Implemented the 'snoop mode', that allows a client to 'snoop' the streams

between another host and a device. It is only implemented for BeBoB devices.
The channel numbers and stream configuration are automatically detected.
Note that it currently relies on a rather hackish support for reading the
{i,o}PCR plugs by using private functions of libiec61883

- changed jack backend to support these two new features

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