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

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

namespace simplification

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 Streaming {
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 Streaming
Note: See TracBrowser for help on using the browser.