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

Revision 399, 50.3 kB (checked in by pieterpalmers, 16 years ago)

- code cleanup
- introduce sync delay concept to fix latency issues due to intermediate ISO buffering
- made SytMonitor? use cycletimer.h functions

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