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

Revision 394, 52.0 kB (checked in by pieterpalmers, 17 years ago)

- fixed SYT timestamp to ticks conversion

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