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

Revision 411, 46.2 kB (checked in by pieterpalmers, 16 years ago)

cycletimer.h:
- some extra operations on Ticks (diffTicks & substractTicks)

StreamProcessor?.cpp
AmdtpStreamProcessor?.cpp
MotuStreamProcessor?.cpp:
- Moved the syncDelay to StreamProcessor::getTimeUntilNextPeriodSignalUsecs(). This delay should be the delay between the actual period boundary and the time it is reported to the SPManager. Therefore it's place is not as a buffer offset, but in the calculation of the signalling time.
This makes that the buffer timestamps correspond to 'real' timestamps. These might have to be manipulated by the transmit or receive handles to account for e.g. iso buffering etc..., but at least the timestamps themselves have a well-defined meaning now.

StreamProcessorManager?.cpp:
- The only stream that needs to be running is the sync source stream. It is assumed that the other streams start running in time. 'In time' is currently about 2000 cycles afterwards.

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  *   Copyright (C) 2006 Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
11  *
12  *   This program is free software {} you can redistribute it and/or modify
13  *   it under the terms of the GNU General Public License as published by
14  *   the Free Software Foundation {} either version 2 of the License, or
15  *   (at your option) any later version.
16  *
17  *   This program is distributed in the hope that it will be useful,
18  *   but WITHOUT ANY WARRANTY {} without even the implied warranty of
19  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *   GNU General Public License for more details.
21  *
22  *   You should have received a copy of the GNU General Public License
23  *   along with this program {} if not, write to the Free Software
24  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25  *
26  *
27  *
28  */
29 #include "MotuStreamProcessor.h"
30 #include "Port.h"
31 #include "MotuPort.h"
32
33 #include <math.h>
34
35 #include <netinet/in.h>
36
37 #include "cycletimer.h"
38
39 // in ticks
40 #define TRANSMIT_TRANSFER_DELAY 6000U
41 // the number of cycles to send a packet in advance of it's timestamp
42 #define TRANSMIT_ADVANCE_CYCLES 1U
43
44 namespace FreebobStreaming {
45
46 IMPL_DEBUG_MODULE( MotuTransmitStreamProcessor, MotuTransmitStreamProcessor, DEBUG_LEVEL_NORMAL );
47 IMPL_DEBUG_MODULE( MotuReceiveStreamProcessor, MotuReceiveStreamProcessor, DEBUG_LEVEL_NORMAL );
48
49 // Set to 1 to enable the generation of a 1 kHz test tone in analog output 1
50 #define TESTTONE 1
51
52 // A macro to extract specific bits from a native endian quadlet
53 #define get_bits(_d,_start,_len) (((_d)>>((_start)-(_len)+1)) & ((1<<(_len))-1))
54
55 /* transmit */
56 MotuTransmitStreamProcessor::MotuTransmitStreamProcessor(int port, int framerate,
57                 unsigned int event_size)
58         : TransmitStreamProcessor(port, framerate), m_event_size(event_size),
59         m_tx_dbc(0),
60         m_closedown_count(-1), m_streaming_active(0) {
61 }
62
63 MotuTransmitStreamProcessor::~MotuTransmitStreamProcessor() {
64
65 }
66
67 bool MotuTransmitStreamProcessor::init() {
68
69         debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing (%p)...\n");
70         // call the parent init
71         // this has to be done before allocating the buffers,
72         // because this sets the buffersizes from the processormanager
73         if(!TransmitStreamProcessor::init()) {
74                 debugFatal("Could not do base class init (%p)\n",this);
75                 return false;
76         }
77
78         return true;
79 }
80
81 void MotuTransmitStreamProcessor::setVerboseLevel(int l) {
82         setDebugLevel(l); // sets the debug level of the current object
83         TransmitStreamProcessor::setVerboseLevel(l); // also set the level of the base class
84 }
85
86
87 enum raw1394_iso_disposition
88 MotuTransmitStreamProcessor::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 // FIXME: the actual delays in the system need to be worked out so
93 // we can get this thing synchronised.  For now this seems to work.
94     uint64_t ts_head, fc;
95
96         quadlet_t *quadlet = (quadlet_t *)data;
97         signed int i;
98        
99     m_last_cycle=cycle;
100    
101     // determine if we want to send a packet or not
102     // note that we can't use getCycleTimer directly here,
103     // because packets are queued in advance. This means that
104     // we the packet we are constructing will be sent out
105     // on 'cycle', not 'now'.
106     unsigned int ctr=m_handler->getCycleTimer();
107     int now_cycles = (int)CYCLE_TIMER_GET_CYCLES(ctr);
108    
109     // the difference between the cycle this
110     // packet is intended for and 'now'
111     int cycle_diff = diffCycles(cycle, now_cycles);
112    
113         // Signal that streaming is still active
114         m_streaming_active = 1;
115
116     // as long as the cycle parameter is not in sync with
117     // the current time, the stream is considered not
118     // to be 'running'
119     // NOTE: this works only at startup
120     if (!m_running && cycle_diff >= 0 && cycle >= 0) {
121             debugOutput(DEBUG_LEVEL_VERBOSE, "Xmit StreamProcessor %p started running at cycle %d\n",this, cycle);
122             m_running=true;
123     }
124
125     if (!m_disabled && m_is_disabled) {
126         // this means that we are trying to enable
127         if ((unsigned int)cycle == m_cycle_to_enable_at) {
128             m_is_disabled=false;
129            
130             debugOutput(DEBUG_LEVEL_VERBOSE,"Enabling StreamProcessor %p at %u\n", this, cycle);
131            
132             // initialize the buffer head & tail
133             m_SyncSource->m_data_buffer->getBufferHeadTimestamp(&ts_head, &fc); // thread safe
134            
135             // the number of cycles the sync source lags (> 0)
136             // or leads (< 0)
137             int sync_lag_cycles=diffCycles(cycle, m_SyncSource->getLastCycle());
138            
139             // account for the cycle lag between sync SP and this SP
140             // the last update of the sync source's timestamps was sync_lag_cycles
141             // cycles before the cycle we are calculating the timestamp for.
142             // if we were to use one-frame buffers, you would expect the
143             // frame that is sent on cycle CT to have a timestamp T1.
144             // ts_head however is for cycle CT-sync_lag_cycles, and lies
145             // therefore sync_lag_cycles * TICKS_PER_CYCLE earlier than
146             // T1.
147             ts_head = addTicks(ts_head, sync_lag_cycles * TICKS_PER_CYCLE);
148            
149             m_data_buffer->setBufferTailTimestamp(ts_head);
150            
151             #ifdef DEBUG
152             if ((unsigned int)m_data_buffer->getFrameCounter() != m_data_buffer->getBufferSize()) {
153                 debugWarning("m_data_buffer->getFrameCounter() != m_data_buffer->getBufferSize()\n");
154             }
155             #endif
156             debugOutput(DEBUG_LEVEL_VERBOSE,"XMIT TS SET: TS=%10lld, LAG=%03d, FC=%4d\n",
157                             ts_head, sync_lag_cycles, m_data_buffer->getFrameCounter());
158         } else {
159             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
160                         "will enable StreamProcessor %p at %u, now is %d\n",
161                         this, m_cycle_to_enable_at, cycle);
162         }
163     } else if (m_disabled && !m_is_disabled) {
164         // trying to disable
165         debugOutput(DEBUG_LEVEL_VERBOSE,"disabling StreamProcessor %p at %u\n",
166                     this, cycle);
167         m_is_disabled=true;
168     }
169
170         // Do housekeeping expected for all packets sent to the MOTU, even
171         // for packets containing no audio data.
172         *sy = 0x00;
173         *tag = 1;      // All MOTU packets have a CIP-like header
174
175
176     // the base timestamp is the one of the next sample in the buffer
177     m_data_buffer->getBufferHeadTimestamp(&ts_head, &fc); // thread safe
178    
179     int64_t timestamp = ts_head;
180
181     // we send a packet some cycles in advance, to avoid the
182     // following situation:
183     // suppose we are only a few ticks away from
184     // the moment to send this packet. therefore we decide
185     // not to send the packet, but send it in the next cycle.
186     // This means that the next time point will be 3072 ticks
187     // later, making that the timestamp will be expired when the
188     // packet is sent, unless TRANSFER_DELAY > 3072.
189     // this means that we need at least one cycle of extra buffering.
190     uint64_t ticks_to_advance = TICKS_PER_CYCLE * TRANSMIT_ADVANCE_CYCLES;
191    
192     // if cycle lies cycle_diff cycles in the future, we should
193     // queue this packet cycle_diff * TICKS_PER_CYCLE earlier than
194     // we would if it were to be sent immediately.
195     ticks_to_advance += cycle_diff * TICKS_PER_CYCLE;
196
197     // determine the 'now' time in ticks
198     uint64_t cycle_timer=CYCLE_TIMER_TO_TICKS(ctr);
199    
200     // time until the packet is to be sent (if > 0: send packet)
201     int32_t until_next=diffTicks(timestamp, cycle_timer + ticks_to_advance);
202    
203         // Size of a single data frame in quadlets
204         unsigned dbs = m_event_size / 4;
205        
206     // don't process the stream when it is not enabled, not running
207     // or when the next sample is not due yet.
208     if((until_next>0) || m_is_disabled || !m_running) {
209         // send dummy packet
210        
211         // construct the packet CIP-like header.  Even if this is a data-less
212         // packet the dbs field is still set as if there were data blocks
213         // present.  For data-less packets the dbc is the same as the previously
214         // transmitted block.
215         *quadlet = htonl(0x00000400 | ((getNodeId()&0x3f)<<24) | m_tx_dbc | (dbs<<16));
216         quadlet++;
217         *quadlet = htonl(0x8222ffff);
218         quadlet++;
219         *length = 8;
220        
221         #warning high-pitched sound protection removed!
222         // In the disabled state simply zero all data sent to the MOTU.  If
223         // a stream of empty packets are sent once iso streaming is enabled
224         // the MOTU tends to emit high-pitched audio (approx 10 kHz) for
225         // some reason.  This is not completely sufficient, however (zeroed
226         // packets must also be sent on iso closedown).
227    
228         // FIXME: Currently we simply send empty packets to the MOTU when
229         // the stream is disabled so the "m_disabled == 0" code is never
230         // executed.  However, this may change in future so it's left in
231         // for the moment for reference.
232         // FIXME: Currently we don't read the buffer at all during closedown.
233         // We could (and silently junk the contents) if it turned out to be
234         // more helpful.
235        
236         return RAW1394_ISO_DEFER;
237     }
238
239         // The number of events expected by the MOTU is solely dependent on
240         // the current sample rate.  An 'event' is one sample from all channels
241         // plus possibly other midi and control data.
242         signed n_events = m_framerate<=48000?8:(m_framerate<=96000?16:32);
243
244     // add the transmit transfer delay to construct the playout time
245     uint64_t ts=addTicks(timestamp, TRANSMIT_TRANSFER_DELAY);
246    
247     if (m_data_buffer->readFrames(n_events, (char *)(data + 8))) {
248    
249         // Increment the dbc (data block count).  This is only done if the
250         // packet will contain events - that is, we are due to send some
251         // data.  Otherwise a pad packet is sent which contains the DBC of
252         // the previously sent packet.  This regime also means that the very
253         // first packet containing data will have a DBC of n_events, which
254         // matches what is observed from other systems.
255         m_tx_dbc += n_events;
256         if (m_tx_dbc > 0xff)
257             m_tx_dbc -= 0x100;
258    
259         // construct the packet CIP-like header.  Even if this is a data-less
260         // packet the dbs field is still set as if there were data blocks
261         // present.  For data-less packets the dbc is the same as the previously
262         // transmitted block.
263         *quadlet = htonl(0x00000400 | ((getNodeId()&0x3f)<<24) | m_tx_dbc | (dbs<<16));
264         quadlet++;
265         *quadlet = htonl(0x8222ffff);
266         quadlet++;
267
268         *length = n_events*m_event_size + 8;
269
270         // convert the timestamp to Motu format
271         // I assume that it is in ticks, and wraps as the cycle timer
272         #warning syt conversion to be done
273        
274                 // FIXME: if we choose to read the buffer even during closedown,
275                 // here is where the data is silenced.
276                 //   if (m_closedown_count >= 0)
277                 //     memset(data+8, 0, read_size);
278                 if (m_closedown_count > 0)
279                         m_closedown_count--;
280
281                 // Set up each frames's SPH.  Note that the (int) typecast
282                 // appears to do rounding.
283
284 float ticks_per_frame = m_SyncSource->m_data_buffer->getRate();
285                 for (i=0; i<n_events; i++, quadlet += dbs) {
286                         unsigned int ts_frame = ts;
287                         ts_frame += (unsigned int)((float)i * ticks_per_frame);
288                         *quadlet = htonl( TICKS_TO_CYCLE_TIMER(ts_frame) );
289                 }
290
291                 // Process all ports that should be handled on a per-packet base
292                 // this is MIDI for AMDTP (due to the need of DBC, which is lost
293                 // when putting the events in the ringbuffer)
294                 // for motu this might also be control data, however as control
295                 // data isn't time specific I would also include it in the period
296                 // based processing
297        
298                 // FIXME: m_tx_dbc probably needs to be initialised to a non-zero
299                 // value somehow so MIDI sync is possible.  For now we ignore
300                 // this issue.
301                 if (!encodePacketPorts((quadlet_t *)(data+8), n_events, m_tx_dbc)) {
302                         debugWarning("Problem encoding Packet Ports\n");
303                 }
304
305         return RAW1394_ISO_OK;
306        
307     } else if (now_cycles<cycle) {
308         // we can still postpone the queueing of the packets
309         return RAW1394_ISO_AGAIN;
310     } else { // there is no more data in the ringbuffer
311
312         debugWarning("Transmit buffer underrun (now %d, queue %d, target %d)\n",
313                  now_cycles, cycle, TICKS_TO_CYCLES(ts));
314
315         // signal underrun
316         m_xruns++;
317
318         // disable the processing, will be re-enabled when
319         // the xrun is handled
320         m_disabled=true;
321         m_is_disabled=true;
322
323         // compose a no-data packet, we should always
324         // send a valid packet
325        
326         // send dummy packet
327        
328         // construct the packet CIP-like header.  Even if this is a data-less
329         // packet the dbs field is still set as if there were data blocks
330         // present.  For data-less packets the dbc is the same as the previously
331         // transmitted block.
332         *quadlet = htonl(0x00000400 | ((getNodeId()&0x3f)<<24) | m_tx_dbc | (dbs<<16));
333         quadlet++;
334         *quadlet = htonl(0x8222ffff);
335         quadlet++;
336         *length = 8;
337
338         return RAW1394_ISO_DEFER;
339     }
340
341     // we shouldn't get here
342     return RAW1394_ISO_ERROR;
343
344 }
345
346 int MotuTransmitStreamProcessor::getMinimalSyncDelay() {
347     return 0;
348 }
349
350 bool MotuTransmitStreamProcessor::prefill() {
351         // this is needed because otherwise there is no data to be
352         // sent when the streaming starts
353    
354         int i = m_nb_buffers;
355         while (i--) {
356                 if(!transferSilence(m_period)) {
357                         debugFatal("Could not prefill transmit stream\n");
358                         return false;
359                 }
360         }
361         return true;
362 }
363
364 bool MotuTransmitStreamProcessor::reset() {
365
366         debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n");
367
368     // we have to make sure that the buffer HEAD timestamp
369     // lies in the future for every possible buffer fill case.
370     int offset=(int)(m_data_buffer->getBufferSize()*m_ticks_per_frame);
371    
372     m_data_buffer->setTickOffset(offset);
373    
374         // reset all non-device specific stuff
375         // i.e. the iso stream and the associated ports
376         if (!TransmitStreamProcessor::reset()) {
377                 debugFatal("Could not do base class reset\n");
378                 return false;
379         }
380
381         // we should prefill the event buffer
382         if (!prefill()) {
383                 debugFatal("Could not prefill buffers\n");
384                 return false;   
385         }
386
387         return true;
388 }
389
390 bool MotuTransmitStreamProcessor::prepare() {
391    
392         debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing...\n");
393    
394         // prepare all non-device specific stuff
395         // i.e. the iso stream and the associated ports
396         if (!TransmitStreamProcessor::prepare()) {
397                 debugFatal("Could not prepare base class\n");
398                 return false;
399         }
400
401         m_PeriodStat.setName("XMT PERIOD");
402         m_PacketStat.setName("XMT PACKET");
403         m_WakeupStat.setName("XMT WAKEUP");
404
405         debugOutput( DEBUG_LEVEL_VERBOSE, "Event size: %d\n", m_event_size);
406    
407         // allocate the event buffer
408         unsigned int ringbuffer_size_frames=m_nb_buffers * m_period;
409
410     // allocate the internal buffer
411     float ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_framerate);
412         unsigned int events_per_frame = m_framerate<=48000?8:(m_framerate<=96000?16:32);
413
414     assert(m_data_buffer);   
415     m_data_buffer->setBufferSize(ringbuffer_size_frames);
416     m_data_buffer->setEventSize(m_event_size/events_per_frame);
417     m_data_buffer->setEventsPerFrame(events_per_frame);
418    
419     m_data_buffer->setUpdatePeriod(m_period);
420     m_data_buffer->setNominalRate(ticks_per_frame);
421    
422     // FIXME: check if the timestamp wraps at one second
423     m_data_buffer->setWrapValue(TICKS_PER_SECOND);
424    
425     m_data_buffer->prepare();
426
427         // Set the parameters of ports we can: we want the audio ports to be
428         // period buffered, and the midi ports to be packet buffered.
429         for ( PortVectorIterator it = m_Ports.begin();
430           it != m_Ports.end();
431           ++it ) {
432                 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
433                 if(!(*it)->setBufferSize(m_period)) {
434                         debugFatal("Could not set buffer size to %d\n",m_period);
435                         return false;
436                 }
437
438                 switch ((*it)->getPortType()) {
439                 case Port::E_Audio:
440                         if (!(*it)->setSignalType(Port::E_PeriodSignalled)) {
441                                 debugFatal("Could not set signal type to PeriodSignalling");
442                                 return false;
443                         }
444                         break;
445
446                 case Port::E_Midi:
447                         if (!(*it)->setSignalType(Port::E_PacketSignalled)) {
448                                 debugFatal("Could not set signal type to PacketSignalling");
449                                 return false;
450                         }
451                         if (!(*it)->setBufferType(Port::E_RingBuffer)) {
452                                 debugFatal("Could not set buffer type");
453                                 return false;
454                         }
455                         if (!(*it)->setDataType(Port::E_MidiEvent)) {
456                                 debugFatal("Could not set data type");
457                                 return false;
458                         }
459                         // FIXME: probably need rate control too.  See
460                         // Port::useRateControl() and AmdtpStreamProcessor.
461                         break;
462                
463                 case Port::E_Control:
464                         if (!(*it)->setSignalType(Port::E_PeriodSignalled)) {
465                                 debugFatal("Could not set signal type to PeriodSignalling");
466                                 return false;
467                         }
468                         break;
469
470                 default:
471                         debugWarning("Unsupported port type specified\n");
472                         break;
473                 }
474         }
475
476         // The API specific settings of the ports are already set before
477         // this routine is called, therefore we can init&prepare the ports
478         if (!initPorts()) {
479                 debugFatal("Could not initialize ports!\n");
480                 return false;
481         }
482
483         if(!preparePorts()) {
484                 debugFatal("Could not initialize ports!\n");
485                 return false;
486         }
487
488         return true;
489 }
490
491 bool MotuTransmitStreamProcessor::prepareForStop() {
492
493         // If the stream is disabled or isn't running there's no need to
494         // wait since the MOTU *should* still be in a "zero data" state.
495         //
496         // If the m_streaming_active flag is 0 it indicates that the
497         // transmit callback hasn't been called since a closedown was
498         // requested when this function was last called.  This effectively
499         // signifies that the streaming thread has been exitted due to an
500         // xrun in either the receive or transmit handlers.  In this case
501         // there's no point in waiting for the closedown count to hit zero
502         // because it never will; the zero data will never get to the MOTU.
503         // It's best to allow an immediate stop and let the xrun handler
504         // proceed as best it can.
505         //
506         // The ability to detect the lack of streaming also prevents the
507         // "wait for stop" in the stream processor manager's stop() method
508         // from hitting its timeout which in turn seems to increase the
509         // probability of a successful recovery.
510         if (m_is_disabled || !isRunning() || !m_streaming_active)
511                 return true;
512
513         if (m_closedown_count < 0) {
514                 // No closedown has been initiated, so start one now.  Set
515                 // the closedown count to the number of zero packets which
516                 // will be sent to the MOTU before closing off the iso
517                 // streams.  FIXME: 128 packets (each containing 8 frames at
518                 // 48 kHz) is the experimentally-determined figure for 48
519                 // kHz with a period size of 1024.  It seems that at least
520                 // one period of zero samples need to be sent to allow for
521                 // inter-thread communication occuring on period boundaries.
522                 // This needs to be confirmed for other rates and period
523                 // sizes.
524                 signed n_events = m_framerate<=48000?8:(m_framerate<=96000?16:32);
525                 m_closedown_count = m_period / n_events;
526
527                 // Set up a test to confirm that streaming is still active.
528                 // If the streaming function hasn't been called by the next
529                 // iteration through this function there's no point in
530                 // continuing since it means the zero data will never get to
531                 // the MOTU.
532                 m_streaming_active = 0;
533                 return false;
534         }
535
536         // We are "go" for closedown once all requested zero packets
537         // (initiated by a previous call to this function) have been sent to
538         // the MOTU.
539         return m_closedown_count == 0;
540 }
541
542 bool MotuTransmitStreamProcessor::prepareForStart() {
543 // Reset some critical variables required so the stream starts cleanly. This
544 // method is called once on every stream restart. Initialisations which should
545 // be done once should be placed in the init() method instead.
546         m_running = 0;
547         m_closedown_count = -1;
548         m_streaming_active = 0;
549
550         // At this point we'll also disable the stream processor here.
551         // At this stage stream processors are always explicitly re-enabled
552         // after being started, so by starting in the disabled state we
553         // ensure that every start will be exactly the same.
554         disable();
555
556         return true;
557 }
558
559 bool MotuTransmitStreamProcessor::prepareForEnable(uint64_t time_to_enable_at) {
560
561     debugOutput(DEBUG_LEVEL_VERBOSE,"Preparing to enable...\n");
562
563     // for the transmit SP, we have to initialize the
564     // buffer timestamp to something sane, because this timestamp
565     // is used when it is SyncSource
566    
567     // the time we initialize to will determine the time at which
568     // the first sample in the buffer will be sent, so we should
569     // make it at least 'time_to_enable_at'
570    
571     uint64_t now=m_handler->getCycleTimer();
572     unsigned int now_secs=CYCLE_TIMER_GET_SECS(now);
573    
574     // check if a wraparound on the secs will happen between
575     // now and the time we start
576     if (CYCLE_TIMER_GET_CYCLES(now)>time_to_enable_at) {
577         // the start will happen in the next second
578         now_secs++;
579         if (now_secs>=128) now_secs=0;
580     }
581    
582 //    uint64_t ts_head= now_secs*TICKS_PER_SECOND;
583     uint64_t ts_head = time_to_enable_at*TICKS_PER_CYCLE;
584    
585     // we also add the nb of cycles we transmit in advance
586     ts_head=addTicks(ts_head, TRANSMIT_ADVANCE_CYCLES*TICKS_PER_CYCLE);
587    
588     m_data_buffer->setBufferTailTimestamp(ts_head);
589
590     if (!StreamProcessor::prepareForEnable(time_to_enable_at)) {
591         debugError("StreamProcessor::prepareForEnable failed\n");
592         return false;
593     }
594
595     return true;
596 }
597
598 bool MotuTransmitStreamProcessor::transferSilence(unsigned int size) {
599     bool retval;
600    
601         // This function should tranfer 'size' frames of 'silence' to the event buffer
602         char *dummybuffer=(char *)calloc(size,m_event_size);
603
604         transmitSilenceBlock(dummybuffer, size, 0);
605
606     // add the silence data to the ringbuffer
607     if(m_data_buffer->writeFrames(size, dummybuffer, 0)) {
608         retval=true;
609     } else {
610         debugWarning("Could not write to event buffer\n");
611         retval=false;
612     }
613
614         free(dummybuffer);
615
616         return retval;
617 }
618
619 bool MotuTransmitStreamProcessor::putFrames(unsigned int nbframes, int64_t ts) {
620     m_PeriodStat.mark(m_data_buffer->getBufferFill());
621    
622     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "MotuTransmitStreamProcessor::putFrames(%d, %llu)\n", nbframes, ts);
623    
624     // transfer the data
625     m_data_buffer->blockProcessWriteFrames(nbframes, ts);
626
627     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " New timestamp: %llu\n", ts);
628
629     return true;
630 }
631
632 /*
633  * write received events to the stream ringbuffers.
634  */
635
636 bool MotuTransmitStreamProcessor::processWriteBlock(char *data,
637                        unsigned int nevents, unsigned int offset) {
638         bool no_problem=true;
639         unsigned int i;
640
641         // FIXME: ensure the MIDI and control streams are all zeroed until
642         // such time as they are fully implemented.
643         for (i=0; i<nevents; i++) {
644                 memset(data+4+i*m_event_size, 0x00, 6);
645         }
646
647         for ( PortVectorIterator it = m_PeriodPorts.begin();
648           it != m_PeriodPorts.end();
649           ++it ) {
650                 // If this port is disabled, don't process it
651                 if((*it)->isDisabled()) {continue;};
652        
653                 //FIXME: make this into a static_cast when not DEBUG?
654                 Port *port=dynamic_cast<Port *>(*it);
655                
656                 switch(port->getPortType()) {
657                
658                 case Port::E_Audio:
659                         if (encodePortToMotuEvents(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
660                                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str());
661                                 no_problem=false;
662                         }
663                         break;
664                 // midi is a packet based port, don't process
665                 //      case MotuPortInfo::E_Midi:
666                 //              break;
667
668                 default: // ignore
669                         break;
670                 }
671         }
672         return no_problem;
673 }
674
675 int MotuTransmitStreamProcessor::transmitSilenceBlock(char *data,
676                        unsigned int nevents, unsigned int offset) {
677         // This is the same as the non-silence version, except that is
678         // doesn't read from the port buffers.
679
680         int problem=0;
681
682         for ( PortVectorIterator it = m_PeriodPorts.begin();
683           it != m_PeriodPorts.end();
684           ++it ) {
685                 //FIXME: make this into a static_cast when not DEBUG?
686                 Port *port=dynamic_cast<Port *>(*it);
687                
688                 switch(port->getPortType()) {
689                
690                 case Port::E_Audio:
691                         if (encodeSilencePortToMotuEvents(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
692                                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str());
693                                 problem=1;
694                         }
695                         break;
696                 // midi is a packet based port, don't process
697                 //      case MotuPortInfo::E_Midi:
698                 //              break;
699
700                 default: // ignore
701                         break;
702                 }
703         }
704         return problem;
705 }
706
707 /**
708  * @brief decode a packet for the packet-based ports
709  *
710  * @param data Packet data
711  * @param nevents number of events in data (including events of other ports & port types)
712  * @param dbc DataBlockCount value for this packet
713  * @return true if all successfull
714  */
715 bool MotuTransmitStreamProcessor::encodePacketPorts(quadlet_t *data, unsigned int nevents,
716                 unsigned int dbc) {
717         bool ok=true;
718         char byte;
719
720         // Use char here since the target address won't necessarily be
721         // aligned; use of an unaligned quadlet_t may cause issues on
722         // certain architectures.  Besides, the target for MIDI data going
723         // directly to the MOTU isn't structured in quadlets anyway; it is a
724         // sequence of 3 unaligned bytes.
725         unsigned char *target = NULL;
726
727         for ( PortVectorIterator it = m_PacketPorts.begin();
728                 it != m_PacketPorts.end();
729                 ++it ) {
730
731                 Port *port=static_cast<Port *>(*it);
732                 assert(port); // this should not fail!!
733
734                 // Currently the only packet type of events for MOTU
735                 // is MIDI in mbla.  However in future control data
736                 // might also be sent via "packet" events.
737                 // assert(pinfo->getFormat()==MotuPortInfo::E_Midi);
738
739                 // FIXME: MIDI output is completely untested at present.
740                 switch (port->getPortType()) {
741                         case Port::E_Midi: {
742                                 MotuMidiPort *mp=static_cast<MotuMidiPort *>(*it);
743
744                                 // Send a byte if we can. MOTU MIDI data is
745                                 // sent using a 3-byte sequence starting at
746                                 // the port's position.  For now we'll
747                                 // always send in the first event of a
748                                 // packet, but this might need refinement
749                                 // later.
750                                 if (mp->canRead()) {
751                                         mp->readEvent(&byte);
752                                         target = (unsigned char *)data + mp->getPosition();
753                                         *(target++) = 0x01;
754                                         *(target++) = 0x00;
755                                         *(target++) = byte;
756                                 }
757                                 break;
758                         }
759                         default:
760                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown packet-type port type %d\n",port->getPortType());
761                                 return ok;       
762                 }
763         }
764
765         return ok;
766 }
767
768 int MotuTransmitStreamProcessor::encodePortToMotuEvents(MotuAudioPort *p, quadlet_t *data,
769                        unsigned int offset, unsigned int nevents) {
770 // Encodes nevents worth of data from the given port into the given buffer.  The
771 // format of the buffer is precisely that which will be sent to the MOTU.
772 // The basic idea:
773 //   iterate over the ports
774 //     * get port buffer address
775 //     * loop over events
776 //         - pick right sample in event based upon PortInfo
777 //         - convert sample from Port format (E_Int24, E_Float, ..) to MOTU
778 //           native format
779 //
780 // We include the ability to start the transfer from the given offset within
781 // the port (expressed in frames) so the 'efficient' transfer method can be
782 // utilised.
783
784         unsigned int j=0;
785
786         // Use char here since the target address won't necessarily be
787         // aligned; use of an unaligned quadlet_t may cause issues on certain
788         // architectures.  Besides, the target (data going directly to the MOTU)
789         // isn't structured in quadlets anyway; it mainly consists of packed
790         // 24-bit integers.
791         unsigned char *target;
792         target = (unsigned char *)data + p->getPosition();
793
794         switch(p->getDataType()) {
795                 default:
796                 case Port::E_Int24:
797                         {
798                                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
799
800                                 assert(nevents + offset <= p->getBufferSize());
801
802                                 // Offset is in frames, but each port is only a single
803                                 // channel, so the number of frames is the same as the
804                                 // number of quadlets to offset (assuming the port buffer
805                                 // uses one quadlet per sample, which is the case currently).
806                                 buffer+=offset;
807
808                                 for(j = 0; j < nevents; j += 1) { // Decode nsamples
809                                         *target = (*buffer >> 16) & 0xff;
810                                         *(target+1) = (*buffer >> 8) & 0xff;
811                                         *(target+2) = (*buffer) & 0xff;
812
813                                         buffer++;
814                                         target+=m_event_size;
815                                 }
816                         }
817                         break;
818                 case Port::E_Float:
819                         {
820                                 const float multiplier = (float)(0x7FFFFF);
821                                 float *buffer=(float *)(p->getBufferAddress());
822
823                                 assert(nevents + offset <= p->getBufferSize());
824
825                                 buffer+=offset;
826
827                                 for(j = 0; j < nevents; j += 1) { // decode max nsamples               
828                                         unsigned int v = (int)(*buffer * multiplier);
829                                         *target = (v >> 16) & 0xff;
830                                         *(target+1) = (v >> 8) & 0xff;
831                                         *(target+2) = v & 0xff;
832
833                                         buffer++;
834                                         target+=m_event_size;
835                                 }
836                         }
837                         break;
838         }
839
840         return 0;
841 }
842
843 int MotuTransmitStreamProcessor::encodeSilencePortToMotuEvents(MotuAudioPort *p, quadlet_t *data,
844                        unsigned int offset, unsigned int nevents) {
845         unsigned int j=0;
846         unsigned char *target = (unsigned char *)data + p->getPosition();
847
848         switch (p->getDataType()) {
849         default:
850         case Port::E_Int24:
851         case Port::E_Float:
852                 for (j = 0; j < nevents; j++) {
853                         *target = *(target+1) = *(target+2) = 0;
854                         target += m_event_size;
855                 }
856                 break;
857         }
858
859         return 0;
860 }
861
862 /* --------------------- RECEIVE ----------------------- */
863
864 MotuReceiveStreamProcessor::MotuReceiveStreamProcessor(int port, int framerate,
865         unsigned int event_size)
866     : ReceiveStreamProcessor(port, framerate), m_event_size(event_size),
867         m_closedown_active(0) {
868
869 }
870
871 MotuReceiveStreamProcessor::~MotuReceiveStreamProcessor() {
872
873 }
874
875 bool MotuReceiveStreamProcessor::init() {
876
877         // call the parent init
878         // this has to be done before allocating the buffers,
879         // because this sets the buffersizes from the processormanager
880         if(!ReceiveStreamProcessor::init()) {
881                 debugFatal("Could not do base class init (%d)\n",this);
882                 return false;
883         }
884
885         return true;
886 }
887
888         // NOTE by PP: timestamp based sync fixes this automagically by
889         //             enforcing that the roundtrip latency is constant:
890         // Detect missed receive cycles
891         // FIXME: it would be nice to advance the rx buffer by the amount of
892         // frames missed.  However, since the MOTU transmits more frames per
893         // cycle than the average and "catches up" with periodic empty
894         // cycles it's not trivial to work out precisely how many frames
895         // were missed.  Ultimately I think we need to do so if sync is to
896         // be maintained across a transient receive failure.
897        
898 enum raw1394_iso_disposition
899 MotuReceiveStreamProcessor::putPacket(unsigned char *data, unsigned int length,
900                   unsigned char channel, unsigned char tag, unsigned char sy,
901                   unsigned int cycle, unsigned int dropped) {
902    
903         enum raw1394_iso_disposition retval=RAW1394_ISO_OK;
904         // this is needed for the base class getLastCycle() to work.
905         // this avoids a function call like StreamProcessor::updateLastCycle()
906     m_last_cycle=cycle;
907
908     // check our enable status
909     if (!m_disabled && m_is_disabled) {
910         // this means that we are trying to enable
911         if (cycle == m_cycle_to_enable_at) {
912             m_is_disabled=false;
913             debugOutput(DEBUG_LEVEL_VERBOSE,"Enabling StreamProcessor %p at %d\n",
914                 this, cycle);
915                
916             // the previous timestamp is the one we need to start with
917             // because we're going to update the buffer again this loop
918             // using writeframes
919             m_data_buffer->setBufferTailTimestamp(m_last_timestamp2);
920
921         } else {
922             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
923                 "will enable StreamProcessor %p at %u, now is %d\n",
924                     this, m_cycle_to_enable_at, cycle);
925         }
926     } else if (m_disabled && !m_is_disabled) {
927         // trying to disable
928         debugOutput(DEBUG_LEVEL_VERBOSE,"disabling StreamProcessor %p at %u\n", this, cycle);
929         m_is_disabled=true;
930     }
931        
932         // If the packet length is 8 bytes (ie: just a CIP-like header)
933         // there is no isodata.
934         if (length > 8) {
935                 // The iso data blocks from the MOTUs comprise a CIP-like
936                 // header followed by a number of events (8 for 1x rates, 16
937                 // for 2x rates, 32 for 4x rates).
938                 quadlet_t *quadlet = (quadlet_t *)data;
939                 unsigned int dbs = get_bits(ntohl(quadlet[0]), 23, 8);  // Size of one event in terms of fdf_size
940                 unsigned int fdf_size = get_bits(ntohl(quadlet[1]), 23, 8) == 0x22 ? 32:0; // Event unit size in bits
941
942                 // Don't even attempt to process a packet if it isn't what
943                 // we expect from a MOTU.  Yes, an FDF value of 32 bears
944                 // little relationship to the actual data (24 bit integer)
945                 // sent by the MOTU - it's one of those areas where MOTU
946                 // have taken a curious detour around the standards.
947                 if (tag!=1 || fdf_size!=32) {
948                         return RAW1394_ISO_OK;
949                 }
950                
951                 // put this after the check because event_length can become 0 on invalid packets
952                 unsigned int event_length = (fdf_size * dbs) / 8;       // Event size in bytes
953                 unsigned int n_events = (length-8) / event_length;
954                
955         //=> store the previous timestamp
956         m_last_timestamp2=m_last_timestamp;
957
958         //=> convert the SYT to a full timestamp in ticks
959 //        m_last_timestamp=sytRecvToFullTicks((uint32_t)ntohl(*(quadlet_t *)(data+8)),
960 //                                        cycle, m_handler->getCycleTimer());
961 //***
962 // FIXME: it given that we later advance this to be the timestamp of the sample immediately following
963 // this packet, it perhaps makes more sense to acquire the timestamp of the last frame in the packet.
964 // Then it's just a matter of adding m_ticks_per_frame rather than frame_size times this.
965 uint32_t first_sph = ntohl(*(quadlet_t *)(data+8));
966 //        m_last_timestamp = ((first_sph & 0x1fff000)>>12)*3072 + (first_sph & 0xfff);
967         m_last_timestamp = CYCLE_TIMER_TO_TICKS(first_sph & 0x1ffffff);
968
969                 // Signal that we're running
970         if(!m_running && n_events && m_last_timestamp2 && m_last_timestamp) {
971             debugOutput(DEBUG_LEVEL_VERBOSE,"Receive StreamProcessor %p started running at %d\n", this, cycle);
972             m_running=true;
973         }
974
975         //=> don't process the stream samples when it is not enabled.
976         if(m_is_disabled) {
977
978             // we keep track of the timestamp here
979             // this makes sure that we will have a somewhat accurate
980             // estimate as to when a period might be ready. i.e. it will not
981             // be ready earlier than this timestamp + period time
982            
983             // the next (possible) sample is not this one, but lies
984             // SYT_INTERVAL * rate later
985             float frame_size=m_framerate<=48000?8:(m_framerate<=96000?16:32);
986             uint64_t ts=addTicks(m_last_timestamp,
987                                  (uint64_t)(frame_size * m_ticks_per_frame));
988
989             // set the timestamp as if there will be a sample put into
990             // the buffer by the next packet.
991             m_data_buffer->setBufferTailTimestamp(ts);
992            
993             return RAW1394_ISO_DEFER;
994         }
995
996                 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "put packet...\n");
997
998         //=> process the packet
999         // add the data payload to the ringbuffer
1000         if(m_data_buffer->writeFrames(n_events, (char *)(data+8), m_last_timestamp)) {
1001             retval=RAW1394_ISO_OK;
1002            
1003             int dbc = get_bits(ntohl(quadlet[0]), 8, 8);
1004            
1005             // process all ports that should be handled on a per-packet base
1006             // this is MIDI for AMDTP (due to the need of DBC)
1007             if (!decodePacketPorts((quadlet_t *)(data+8), n_events, dbc)) {
1008                 debugWarning("Problem decoding Packet Ports\n");
1009                 retval=RAW1394_ISO_DEFER;
1010             }
1011            
1012         } else {
1013        
1014             debugWarning("Receive buffer overrun (cycle %d, FC=%d, PC=%d)\n",
1015                  cycle, m_data_buffer->getFrameCounter(), m_handler->getPacketCount());
1016            
1017             m_xruns++;
1018            
1019             // disable the processing, will be re-enabled when
1020             // the xrun is handled
1021             m_disabled=true;
1022             m_is_disabled=true;
1023
1024             retval=RAW1394_ISO_DEFER;
1025         }
1026     }
1027
1028         return retval;
1029 }
1030
1031 // returns the delay between the actual (real) time of a timestamp as received,
1032 // and the timestamp that is passed on for the same event. This is to cope with
1033 // ISO buffering
1034 int MotuReceiveStreamProcessor::getMinimalSyncDelay() {
1035         unsigned int n_events = m_framerate<=48000?8:(m_framerate<=96000?16:32);
1036    
1037     return (int)(m_handler->getWakeupInterval() * n_events * m_ticks_per_frame);
1038 }
1039
1040 bool MotuReceiveStreamProcessor::reset() {
1041
1042         debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n");
1043
1044     m_data_buffer->setTickOffset(0);
1045
1046         // reset all non-device specific stuff
1047         // i.e. the iso stream and the associated ports
1048         if(!ReceiveStreamProcessor::reset()) {
1049                 debugFatal("Could not do base class reset\n");
1050                 return false;
1051         }
1052
1053         return true;
1054 }
1055
1056 bool MotuReceiveStreamProcessor::prepare() {
1057
1058         // prepare all non-device specific stuff
1059         // i.e. the iso stream and the associated ports
1060         if(!ReceiveStreamProcessor::prepare()) {
1061                 debugFatal("Could not prepare base class\n");
1062                 return false;
1063         }
1064
1065         debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing...\n");
1066
1067         m_PeriodStat.setName("RCV PERIOD");
1068         m_PacketStat.setName("RCV PACKET");
1069         m_WakeupStat.setName("RCV WAKEUP");
1070
1071     // setup any specific stuff here
1072     // FIXME: m_frame_size would be a better name
1073         debugOutput( DEBUG_LEVEL_VERBOSE, "Event size: %d\n", m_event_size);
1074    
1075     // prepare the framerate estimate
1076     float ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_framerate);
1077        
1078         // initialize internal buffer
1079         unsigned int ringbuffer_size_frames=m_nb_buffers * m_period;
1080        
1081         unsigned int events_per_frame = m_framerate<=48000?8:(m_framerate<=96000?16:32);
1082
1083     assert(m_data_buffer);   
1084     m_data_buffer->setBufferSize(ringbuffer_size_frames);
1085     m_data_buffer->setEventSize(m_event_size/events_per_frame);
1086     m_data_buffer->setEventsPerFrame(events_per_frame);
1087    
1088     m_data_buffer->setUpdatePeriod(m_period);
1089     m_data_buffer->setNominalRate(ticks_per_frame);
1090    
1091     m_data_buffer->setWrapValue(TICKS_PER_SECOND);
1092    
1093     m_data_buffer->prepare();
1094
1095         // set the parameters of ports we can:
1096         // we want the audio ports to be period buffered,
1097         // and the midi ports to be packet buffered
1098         for ( PortVectorIterator it = m_Ports.begin();
1099                   it != m_Ports.end();
1100                   ++it )
1101         {
1102                 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
1103                
1104                 if(!(*it)->setBufferSize(m_period)) {
1105                         debugFatal("Could not set buffer size to %d\n",m_period);
1106                         return false;
1107                 }
1108
1109                 switch ((*it)->getPortType()) {
1110                         case Port::E_Audio:
1111                                 if(!(*it)->setSignalType(Port::E_PeriodSignalled)) {
1112                                         debugFatal("Could not set signal type to PeriodSignalling");
1113                                         return false;
1114                                 }
1115                                 break;
1116                         case Port::E_Midi:
1117                                 if(!(*it)->setSignalType(Port::E_PacketSignalled)) {
1118                                         debugFatal("Could not set signal type to PacketSignalling");
1119                                         return false;
1120                                 }
1121                                 if (!(*it)->setBufferType(Port::E_RingBuffer)) {
1122                                         debugFatal("Could not set buffer type");
1123                                         return false;
1124                                 }
1125                                 if (!(*it)->setDataType(Port::E_MidiEvent)) {
1126                                         debugFatal("Could not set data type");
1127                                         return false;
1128                                 }
1129                                 // FIXME: probably need rate control too.  See
1130                                 // Port::useRateControl() and AmdtpStreamProcessor.
1131                                 break;
1132                         case Port::E_Control:
1133                                 if(!(*it)->setSignalType(Port::E_PeriodSignalled)) {
1134                                         debugFatal("Could not set signal type to PeriodSignalling");
1135                                         return false;
1136                                 }
1137                                 break;
1138                         default:
1139                                 debugWarning("Unsupported port type specified\n");
1140                                 break;
1141                 }
1142
1143         }
1144
1145         // The API specific settings of the ports are already set before
1146         // this routine is called, therefore we can init&prepare the ports
1147         if(!initPorts()) {
1148                 debugFatal("Could not initialize ports!\n");
1149                 return false;
1150         }
1151
1152         if(!preparePorts()) {
1153                 debugFatal("Could not initialize ports!\n");
1154                 return false;
1155         }
1156        
1157         return true;
1158
1159 }
1160
1161
1162 bool MotuReceiveStreamProcessor::prepareForStop() {
1163
1164         // A MOTU receive stream can stop at any time.  However, signify
1165         // that stopping is in progress because other streams (notably the
1166         // transmit stream) may keep going for some time and cause an
1167         // overflow in the receive buffers.  If a closedown is in progress
1168         // the receive handler simply throws all incoming data away so
1169         // no buffer overflow can occur.
1170         m_closedown_active = 1;
1171         return true;
1172 }
1173
1174 bool MotuReceiveStreamProcessor::prepareForStart() {
1175 // Reset some critical variables required so the stream starts cleanly. This
1176 // method is called once on every stream restart, including those during
1177 // xrun recovery.  Initialisations which should be done once should be
1178 // placed in the init() method instead.
1179         m_running = 0;
1180         m_closedown_active = 0;
1181
1182         // At this point we'll also disable the stream processor here.
1183         // At this stage stream processors are always explicitly re-enabled
1184         // after being started, so by starting in the disabled state we
1185         // ensure that every start will be exactly the same.
1186         disable();
1187
1188         return true;
1189 }
1190
1191 bool MotuReceiveStreamProcessor::getFrames(unsigned int nbframes) {
1192
1193     m_PeriodStat.mark(m_data_buffer->getBufferFill());
1194
1195     // ask the buffer to process nbframes of frames
1196     // using it's registered client's processReadBlock(),
1197     // which should be ours
1198     m_data_buffer->blockProcessReadFrames(nbframes);
1199
1200     return true;
1201 }
1202
1203 /**
1204  * \brief write received events to the port ringbuffers.
1205  */
1206 bool MotuReceiveStreamProcessor::processReadBlock(char *data,
1207                                            unsigned int nevents, unsigned int offset)
1208 {
1209         bool no_problem=true;
1210         for ( PortVectorIterator it = m_PeriodPorts.begin();
1211           it != m_PeriodPorts.end();
1212           ++it ) {
1213                 if((*it)->isDisabled()) {continue;};
1214
1215                 //FIXME: make this into a static_cast when not DEBUG?
1216                 Port *port=dynamic_cast<Port *>(*it);
1217                
1218                 switch(port->getPortType()) {
1219                
1220                 case Port::E_Audio:
1221                         if(decodeMotuEventsToPort(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
1222                                 debugWarning("Could not decode packet MBLA to port %s",(*it)->getName().c_str());
1223                                 no_problem=false;
1224                         }
1225                         break;
1226                 // midi is a packet based port, don't process
1227                 //      case MotuPortInfo::E_Midi:
1228                 //              break;
1229
1230                 default: // ignore
1231                         break;
1232                 }
1233         }
1234         return no_problem;
1235 }
1236
1237 /**
1238  * @brief decode a packet for the packet-based ports
1239  *
1240  * @param data Packet data
1241  * @param nevents number of events in data (including events of other ports & port types)
1242  * @param dbc DataBlockCount value for this packet
1243  * @return true if all successfull
1244  */
1245 bool MotuReceiveStreamProcessor::decodePacketPorts(quadlet_t *data, unsigned int nevents,
1246                 unsigned int dbc) {
1247         bool ok=true;
1248
1249         // Use char here since the source address won't necessarily be
1250         // aligned; use of an unaligned quadlet_t may cause issues on
1251         // certain architectures.  Besides, the source for MIDI data going
1252         // directly to the MOTU isn't structured in quadlets anyway; it is a
1253         // sequence of 3 unaligned bytes.
1254         unsigned char *src = NULL;
1255
1256         for ( PortVectorIterator it = m_PacketPorts.begin();
1257                 it != m_PacketPorts.end();
1258                 ++it ) {
1259
1260                 Port *port=dynamic_cast<Port *>(*it);
1261                 assert(port); // this should not fail!!
1262
1263                 // Currently the only packet type of events for MOTU
1264                 // is MIDI in mbla.  However in future control data
1265                 // might also be sent via "packet" events, so allow
1266                 // for this possible expansion.
1267
1268                 // FIXME: MIDI input is completely untested at present.
1269                 switch (port->getPortType()) {
1270                         case Port::E_Midi: {
1271                                 MotuMidiPort *mp=static_cast<MotuMidiPort *>(*it);
1272                                 signed int sample;
1273                                 unsigned int j = 0;
1274                                 // Get MIDI bytes if present anywhere in the
1275                                 // packet.  MOTU MIDI data is sent using a
1276                                 // 3-byte sequence starting at the port's
1277                                 // position.  It's thought that there can never
1278                                 // be more than one MIDI byte per packet, but
1279                                 // for completeness we'll check the entire packet
1280                                 // anyway.
1281                                 src = (unsigned char *)data + mp->getPosition();
1282                                 while (j < nevents) {
1283                                         if (*src==0x01 && *(src+1)==0x00) {
1284                                                 sample = *(src+2);
1285                                                 if (!mp->writeEvent(&sample)) {
1286                                                         debugWarning("MIDI packet port events lost\n");
1287                                                         ok = false;
1288                                                 }
1289                                         }
1290                                         j++;
1291                                         src += m_event_size;
1292                                 }
1293                                 break;
1294                         }
1295                         default:
1296                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown packet-type port format %d\n",port->getPortType());
1297                                 return ok;       
1298                 }
1299         }
1300
1301         return ok;
1302 }
1303
1304 signed int MotuReceiveStreamProcessor::decodeMotuEventsToPort(MotuAudioPort *p,
1305                 quadlet_t *data, unsigned int offset, unsigned int nevents)
1306 {
1307         unsigned int j=0;
1308
1309         // Use char here since a port's source address won't necessarily be
1310         // aligned; use of an unaligned quadlet_t may cause issues on
1311         // certain architectures.  Besides, the source (data coming directly
1312         // from the MOTU) isn't structured in quadlets anyway; it mainly
1313         // consists of packed 24-bit integers.
1314
1315         unsigned char *src_data;
1316         src_data = (unsigned char *)data + p->getPosition();
1317
1318         switch(p->getDataType()) {
1319                 default:
1320                 case Port::E_Int24:
1321                         {
1322                                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
1323
1324                                 assert(nevents + offset <= p->getBufferSize());
1325
1326                                 // Offset is in frames, but each port is only a single
1327                                 // channel, so the number of frames is the same as the
1328                                 // number of quadlets to offset (assuming the port buffer
1329                                 // uses one quadlet per sample, which is the case currently).
1330                                 buffer+=offset;
1331
1332                                 for(j = 0; j < nevents; j += 1) { // Decode nsamples
1333                                         *buffer = (*src_data<<16)+(*(src_data+1)<<8)+*(src_data+2);
1334                                         // Sign-extend highest bit of 24-bit int.
1335                                         // FIXME: this isn't strictly needed since E_Int24 is a 24-bit,
1336                                         // but doing so shouldn't break anything and makes the data
1337                                         // easier to deal with during debugging.
1338                                         if (*src_data & 0x80)
1339                                                 *buffer |= 0xff000000;
1340
1341                                         buffer++;
1342                                         src_data+=m_event_size;
1343                                 }
1344                         }
1345                         break;
1346                 case Port::E_Float:
1347                         {
1348                                 const float multiplier = 1.0f / (float)(0x7FFFFF);
1349                                 float *buffer=(float *)(p->getBufferAddress());
1350
1351                                 assert(nevents + offset <= p->getBufferSize());
1352
1353                                 buffer+=offset;
1354
1355                                 for(j = 0; j < nevents; j += 1) { // decode max nsamples               
1356        
1357                                         unsigned int v = (*src_data<<16)+(*(src_data+1)<<8)+*(src_data+2);
1358
1359                                         // sign-extend highest bit of 24-bit int
1360                                         int tmp = (int)(v << 8) / 256;
1361                
1362                                         *buffer = tmp * multiplier;
1363                                
1364                                         buffer++;
1365                                         src_data+=m_event_size;
1366                                 }
1367                         }
1368                         break;
1369         }
1370
1371         return 0;
1372 }
1373
1374 signed int MotuReceiveStreamProcessor::setEventSize(unsigned int size) {
1375         m_event_size = size;
1376         return 0;
1377 }
1378
1379 unsigned int MotuReceiveStreamProcessor::getEventSize(void) {
1380 //
1381 // Return the size of a single event sent by the MOTU as part of an iso
1382 // data packet in bytes.
1383 //
1384         return m_event_size;
1385 }
1386
1387 void MotuReceiveStreamProcessor::setVerboseLevel(int l) {
1388         setDebugLevel(l);
1389         ReceiveStreamProcessor::setVerboseLevel(l);
1390 }
1391
1392 } // end of namespace FreebobStreaming
Note: See TracBrowser for help on using the browser.