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

Revision 410, 47.0 kB (checked in by jwoithe, 17 years ago)

MOTU: rough fixups towards restoring functionality under the new streaming framework. It is not yet functional.

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 = substractCycles(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 != -1) {
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=substractCycles(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     int64_t until_next=substractTicks(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     // we can substract the delay as it introduces
373     // unnescessary delay
374     offset -= m_SyncSource->getSyncDelay();
375    
376     m_data_buffer->setTickOffset(offset);
377    
378         // reset all non-device specific stuff
379         // i.e. the iso stream and the associated ports
380         if (!TransmitStreamProcessor::reset()) {
381                 debugFatal("Could not do base class reset\n");
382                 return false;
383         }
384
385         // we should prefill the event buffer
386         if (!prefill()) {
387                 debugFatal("Could not prefill buffers\n");
388                 return false;   
389         }
390
391         return true;
392 }
393
394 bool MotuTransmitStreamProcessor::prepare() {
395    
396         debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing...\n");
397    
398         // prepare all non-device specific stuff
399         // i.e. the iso stream and the associated ports
400         if (!TransmitStreamProcessor::prepare()) {
401                 debugFatal("Could not prepare base class\n");
402                 return false;
403         }
404
405         m_PeriodStat.setName("XMT PERIOD");
406         m_PacketStat.setName("XMT PACKET");
407         m_WakeupStat.setName("XMT WAKEUP");
408
409         debugOutput( DEBUG_LEVEL_VERBOSE, "Event size: %d\n", m_event_size);
410    
411         // allocate the event buffer
412         unsigned int ringbuffer_size_frames=m_nb_buffers * m_period;
413
414     // allocate the internal buffer
415     float ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_framerate);
416         unsigned int events_per_frame = m_framerate<=48000?8:(m_framerate<=96000?16:32);
417
418     assert(m_data_buffer);   
419     m_data_buffer->setBufferSize(ringbuffer_size_frames);
420     m_data_buffer->setEventSize(m_event_size/events_per_frame);
421     m_data_buffer->setEventsPerFrame(events_per_frame);
422    
423     m_data_buffer->setUpdatePeriod(m_period);
424     m_data_buffer->setNominalRate(ticks_per_frame);
425    
426     // FIXME: check if the timestamp wraps at one second
427     m_data_buffer->setWrapValue(TICKS_PER_SECOND);
428    
429     m_data_buffer->prepare();
430
431         // Set the parameters of ports we can: we want the audio ports to be
432         // period buffered, and the midi ports to be packet buffered.
433         for ( PortVectorIterator it = m_Ports.begin();
434           it != m_Ports.end();
435           ++it ) {
436                 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
437                 if(!(*it)->setBufferSize(m_period)) {
438                         debugFatal("Could not set buffer size to %d\n",m_period);
439                         return false;
440                 }
441
442                 switch ((*it)->getPortType()) {
443                 case Port::E_Audio:
444                         if (!(*it)->setSignalType(Port::E_PeriodSignalled)) {
445                                 debugFatal("Could not set signal type to PeriodSignalling");
446                                 return false;
447                         }
448                         break;
449
450                 case Port::E_Midi:
451                         if (!(*it)->setSignalType(Port::E_PacketSignalled)) {
452                                 debugFatal("Could not set signal type to PacketSignalling");
453                                 return false;
454                         }
455                         if (!(*it)->setBufferType(Port::E_RingBuffer)) {
456                                 debugFatal("Could not set buffer type");
457                                 return false;
458                         }
459                         if (!(*it)->setDataType(Port::E_MidiEvent)) {
460                                 debugFatal("Could not set data type");
461                                 return false;
462                         }
463                         // FIXME: probably need rate control too.  See
464                         // Port::useRateControl() and AmdtpStreamProcessor.
465                         break;
466                
467                 case Port::E_Control:
468                         if (!(*it)->setSignalType(Port::E_PeriodSignalled)) {
469                                 debugFatal("Could not set signal type to PeriodSignalling");
470                                 return false;
471                         }
472                         break;
473
474                 default:
475                         debugWarning("Unsupported port type specified\n");
476                         break;
477                 }
478         }
479
480         // The API specific settings of the ports are already set before
481         // this routine is called, therefore we can init&prepare the ports
482         if (!initPorts()) {
483                 debugFatal("Could not initialize ports!\n");
484                 return false;
485         }
486
487         if(!preparePorts()) {
488                 debugFatal("Could not initialize ports!\n");
489                 return false;
490         }
491
492         return true;
493 }
494
495 bool MotuTransmitStreamProcessor::prepareForStop() {
496
497         // If the stream is disabled or isn't running there's no need to
498         // wait since the MOTU *should* still be in a "zero data" state.
499         //
500         // If the m_streaming_active flag is 0 it indicates that the
501         // transmit callback hasn't been called since a closedown was
502         // requested when this function was last called.  This effectively
503         // signifies that the streaming thread has been exitted due to an
504         // xrun in either the receive or transmit handlers.  In this case
505         // there's no point in waiting for the closedown count to hit zero
506         // because it never will; the zero data will never get to the MOTU.
507         // It's best to allow an immediate stop and let the xrun handler
508         // proceed as best it can.
509         //
510         // The ability to detect the lack of streaming also prevents the
511         // "wait for stop" in the stream processor manager's stop() method
512         // from hitting its timeout which in turn seems to increase the
513         // probability of a successful recovery.
514         if (m_is_disabled || !isRunning() || !m_streaming_active)
515                 return true;
516
517         if (m_closedown_count < 0) {
518                 // No closedown has been initiated, so start one now.  Set
519                 // the closedown count to the number of zero packets which
520                 // will be sent to the MOTU before closing off the iso
521                 // streams.  FIXME: 128 packets (each containing 8 frames at
522                 // 48 kHz) is the experimentally-determined figure for 48
523                 // kHz with a period size of 1024.  It seems that at least
524                 // one period of zero samples need to be sent to allow for
525                 // inter-thread communication occuring on period boundaries.
526                 // This needs to be confirmed for other rates and period
527                 // sizes.
528                 signed n_events = m_framerate<=48000?8:(m_framerate<=96000?16:32);
529                 m_closedown_count = m_period / n_events;
530
531                 // Set up a test to confirm that streaming is still active.
532                 // If the streaming function hasn't been called by the next
533                 // iteration through this function there's no point in
534                 // continuing since it means the zero data will never get to
535                 // the MOTU.
536                 m_streaming_active = 0;
537                 return false;
538         }
539
540         // We are "go" for closedown once all requested zero packets
541         // (initiated by a previous call to this function) have been sent to
542         // the MOTU.
543         return m_closedown_count == 0;
544 }
545
546 bool MotuTransmitStreamProcessor::prepareForStart() {
547 // Reset some critical variables required so the stream starts cleanly. This
548 // method is called once on every stream restart. Initialisations which should
549 // be done once should be placed in the init() method instead.
550         m_running = 0;
551         m_closedown_count = -1;
552         m_streaming_active = 0;
553
554         // At this point we'll also disable the stream processor here.
555         // At this stage stream processors are always explicitly re-enabled
556         // after being started, so by starting in the disabled state we
557         // ensure that every start will be exactly the same.
558         disable();
559
560         return true;
561 }
562
563 bool MotuTransmitStreamProcessor::prepareForEnable(uint64_t time_to_enable_at) {
564
565     debugOutput(DEBUG_LEVEL_VERBOSE,"Preparing to enable...\n");
566
567     // for the transmit SP, we have to initialize the
568     // buffer timestamp to something sane, because this timestamp
569     // is used when it is SyncSource
570    
571     // the time we initialize to will determine the time at which
572     // the first sample in the buffer will be sent, so we should
573     // make it at least 'time_to_enable_at'
574    
575     uint64_t now=m_handler->getCycleTimer();
576     unsigned int now_secs=CYCLE_TIMER_GET_SECS(now);
577    
578     // check if a wraparound on the secs will happen between
579     // now and the time we start
580     if (CYCLE_TIMER_GET_CYCLES(now)>time_to_enable_at) {
581         // the start will happen in the next second
582         now_secs++;
583         if (now_secs>=128) now_secs=0;
584     }
585    
586 //    uint64_t ts_head= now_secs*TICKS_PER_SECOND;
587     uint64_t ts_head = time_to_enable_at*TICKS_PER_CYCLE;
588    
589     // we also add the nb of cycles we transmit in advance
590     ts_head=addTicks(ts_head, TRANSMIT_ADVANCE_CYCLES*TICKS_PER_CYCLE);
591    
592     m_data_buffer->setBufferTailTimestamp(ts_head);
593
594
595     if (!StreamProcessor::prepareForEnable(time_to_enable_at)) {
596         debugError("StreamProcessor::prepareForEnable failed\n");
597         return false;
598     }
599
600     return true;
601 }
602
603 bool MotuTransmitStreamProcessor::transferSilence(unsigned int size) {
604     bool retval;
605    
606         // This function should tranfer 'size' frames of 'silence' to the event buffer
607         char *dummybuffer=(char *)calloc(size,m_event_size);
608
609         transmitSilenceBlock(dummybuffer, size, 0);
610
611     // add the silence data to the ringbuffer
612     if(m_data_buffer->writeFrames(size, dummybuffer, 0)) {
613         retval=true;
614     } else {
615         debugWarning("Could not write to event buffer\n");
616         retval=false;
617     }
618
619         free(dummybuffer);
620
621         return retval;
622 }
623
624 bool MotuTransmitStreamProcessor::putFrames(unsigned int nbframes, int64_t ts) {
625     m_PeriodStat.mark(m_data_buffer->getBufferFill());
626    
627     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "MotuTransmitStreamProcessor::putFrames(%d, %llu)\n", nbframes, ts);
628    
629     // transfer the data
630     m_data_buffer->blockProcessWriteFrames(nbframes, ts);
631
632     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " New timestamp: %llu\n", ts);
633
634     return true;
635 }
636
637 /*
638  * write received events to the stream ringbuffers.
639  */
640
641 bool MotuTransmitStreamProcessor::processWriteBlock(char *data,
642                        unsigned int nevents, unsigned int offset) {
643         bool no_problem=true;
644         unsigned int i;
645
646         // FIXME: ensure the MIDI and control streams are all zeroed until
647         // such time as they are fully implemented.
648         for (i=0; i<nevents; i++) {
649                 memset(data+4+i*m_event_size, 0x00, 6);
650         }
651
652         for ( PortVectorIterator it = m_PeriodPorts.begin();
653           it != m_PeriodPorts.end();
654           ++it ) {
655                 // If this port is disabled, don't process it
656                 if((*it)->isDisabled()) {continue;};
657        
658                 //FIXME: make this into a static_cast when not DEBUG?
659                 Port *port=dynamic_cast<Port *>(*it);
660                
661                 switch(port->getPortType()) {
662                
663                 case Port::E_Audio:
664                         if (encodePortToMotuEvents(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
665                                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str());
666                                 no_problem=false;
667                         }
668                         break;
669                 // midi is a packet based port, don't process
670                 //      case MotuPortInfo::E_Midi:
671                 //              break;
672
673                 default: // ignore
674                         break;
675                 }
676         }
677         return no_problem;
678 }
679
680 int MotuTransmitStreamProcessor::transmitSilenceBlock(char *data,
681                        unsigned int nevents, unsigned int offset) {
682         // This is the same as the non-silence version, except that is
683         // doesn't read from the port buffers.
684
685         int problem=0;
686
687         for ( PortVectorIterator it = m_PeriodPorts.begin();
688           it != m_PeriodPorts.end();
689           ++it ) {
690                 //FIXME: make this into a static_cast when not DEBUG?
691                 Port *port=dynamic_cast<Port *>(*it);
692                
693                 switch(port->getPortType()) {
694                
695                 case Port::E_Audio:
696                         if (encodeSilencePortToMotuEvents(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
697                                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str());
698                                 problem=1;
699                         }
700                         break;
701                 // midi is a packet based port, don't process
702                 //      case MotuPortInfo::E_Midi:
703                 //              break;
704
705                 default: // ignore
706                         break;
707                 }
708         }
709         return problem;
710 }
711
712 /**
713  * @brief decode a packet for the packet-based ports
714  *
715  * @param data Packet data
716  * @param nevents number of events in data (including events of other ports & port types)
717  * @param dbc DataBlockCount value for this packet
718  * @return true if all successfull
719  */
720 bool MotuTransmitStreamProcessor::encodePacketPorts(quadlet_t *data, unsigned int nevents,
721                 unsigned int dbc) {
722         bool ok=true;
723         char byte;
724
725         // Use char here since the target address won't necessarily be
726         // aligned; use of an unaligned quadlet_t may cause issues on
727         // certain architectures.  Besides, the target for MIDI data going
728         // directly to the MOTU isn't structured in quadlets anyway; it is a
729         // sequence of 3 unaligned bytes.
730         unsigned char *target = NULL;
731
732         for ( PortVectorIterator it = m_PacketPorts.begin();
733                 it != m_PacketPorts.end();
734                 ++it ) {
735
736                 Port *port=static_cast<Port *>(*it);
737                 assert(port); // this should not fail!!
738
739                 // Currently the only packet type of events for MOTU
740                 // is MIDI in mbla.  However in future control data
741                 // might also be sent via "packet" events.
742                 // assert(pinfo->getFormat()==MotuPortInfo::E_Midi);
743
744                 // FIXME: MIDI output is completely untested at present.
745                 switch (port->getPortType()) {
746                         case Port::E_Midi: {
747                                 MotuMidiPort *mp=static_cast<MotuMidiPort *>(*it);
748
749                                 // Send a byte if we can. MOTU MIDI data is
750                                 // sent using a 3-byte sequence starting at
751                                 // the port's position.  For now we'll
752                                 // always send in the first event of a
753                                 // packet, but this might need refinement
754                                 // later.
755                                 if (mp->canRead()) {
756                                         mp->readEvent(&byte);
757                                         target = (unsigned char *)data + mp->getPosition();
758                                         *(target++) = 0x01;
759                                         *(target++) = 0x00;
760                                         *(target++) = byte;
761                                 }
762                                 break;
763                         }
764                         default:
765                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown packet-type port type %d\n",port->getPortType());
766                                 return ok;       
767                 }
768         }
769
770         return ok;
771 }
772
773 int MotuTransmitStreamProcessor::encodePortToMotuEvents(MotuAudioPort *p, quadlet_t *data,
774                        unsigned int offset, unsigned int nevents) {
775 // Encodes nevents worth of data from the given port into the given buffer.  The
776 // format of the buffer is precisely that which will be sent to the MOTU.
777 // The basic idea:
778 //   iterate over the ports
779 //     * get port buffer address
780 //     * loop over events
781 //         - pick right sample in event based upon PortInfo
782 //         - convert sample from Port format (E_Int24, E_Float, ..) to MOTU
783 //           native format
784 //
785 // We include the ability to start the transfer from the given offset within
786 // the port (expressed in frames) so the 'efficient' transfer method can be
787 // utilised.
788
789         unsigned int j=0;
790
791         // Use char here since the target address won't necessarily be
792         // aligned; use of an unaligned quadlet_t may cause issues on certain
793         // architectures.  Besides, the target (data going directly to the MOTU)
794         // isn't structured in quadlets anyway; it mainly consists of packed
795         // 24-bit integers.
796         unsigned char *target;
797         target = (unsigned char *)data + p->getPosition();
798
799         switch(p->getDataType()) {
800                 default:
801                 case Port::E_Int24:
802                         {
803                                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
804
805                                 assert(nevents + offset <= p->getBufferSize());
806
807                                 // Offset is in frames, but each port is only a single
808                                 // channel, so the number of frames is the same as the
809                                 // number of quadlets to offset (assuming the port buffer
810                                 // uses one quadlet per sample, which is the case currently).
811                                 buffer+=offset;
812
813                                 for(j = 0; j < nevents; j += 1) { // Decode nsamples
814                                         *target = (*buffer >> 16) & 0xff;
815                                         *(target+1) = (*buffer >> 8) & 0xff;
816                                         *(target+2) = (*buffer) & 0xff;
817
818                                         buffer++;
819                                         target+=m_event_size;
820                                 }
821                         }
822                         break;
823                 case Port::E_Float:
824                         {
825                                 const float multiplier = (float)(0x7FFFFF);
826                                 float *buffer=(float *)(p->getBufferAddress());
827
828                                 assert(nevents + offset <= p->getBufferSize());
829
830                                 buffer+=offset;
831
832                                 for(j = 0; j < nevents; j += 1) { // decode max nsamples               
833                                         unsigned int v = (int)(*buffer * multiplier);
834                                         *target = (v >> 16) & 0xff;
835                                         *(target+1) = (v >> 8) & 0xff;
836                                         *(target+2) = v & 0xff;
837
838                                         buffer++;
839                                         target+=m_event_size;
840                                 }
841                         }
842                         break;
843         }
844
845         return 0;
846 }
847
848 int MotuTransmitStreamProcessor::encodeSilencePortToMotuEvents(MotuAudioPort *p, quadlet_t *data,
849                        unsigned int offset, unsigned int nevents) {
850         unsigned int j=0;
851         unsigned char *target = (unsigned char *)data + p->getPosition();
852
853         switch (p->getDataType()) {
854         default:
855         case Port::E_Int24:
856         case Port::E_Float:
857                 for (j = 0; j < nevents; j++) {
858                         *target = *(target+1) = *(target+2) = 0;
859                         target += m_event_size;
860                 }
861                 break;
862         }
863
864         return 0;
865 }
866
867 /* --------------------- RECEIVE ----------------------- */
868
869 MotuReceiveStreamProcessor::MotuReceiveStreamProcessor(int port, int framerate,
870         unsigned int event_size)
871     : ReceiveStreamProcessor(port, framerate), m_event_size(event_size),
872         m_closedown_active(0) {
873
874 }
875
876 MotuReceiveStreamProcessor::~MotuReceiveStreamProcessor() {
877
878 }
879
880 bool MotuReceiveStreamProcessor::init() {
881
882         // call the parent init
883         // this has to be done before allocating the buffers,
884         // because this sets the buffersizes from the processormanager
885         if(!ReceiveStreamProcessor::init()) {
886                 debugFatal("Could not do base class init (%d)\n",this);
887                 return false;
888         }
889
890         return true;
891 }
892
893         // NOTE by PP: timestamp based sync fixes this automagically by
894         //             enforcing that the roundtrip latency is constant:
895         // Detect missed receive cycles
896         // FIXME: it would be nice to advance the rx buffer by the amount of
897         // frames missed.  However, since the MOTU transmits more frames per
898         // cycle than the average and "catches up" with periodic empty
899         // cycles it's not trivial to work out precisely how many frames
900         // were missed.  Ultimately I think we need to do so if sync is to
901         // be maintained across a transient receive failure.
902        
903 enum raw1394_iso_disposition
904 MotuReceiveStreamProcessor::putPacket(unsigned char *data, unsigned int length,
905                   unsigned char channel, unsigned char tag, unsigned char sy,
906                   unsigned int cycle, unsigned int dropped) {
907    
908         enum raw1394_iso_disposition retval=RAW1394_ISO_OK;
909         // this is needed for the base class getLastCycle() to work.
910         // this avoids a function call like StreamProcessor::updateLastCycle()
911     m_last_cycle=cycle;
912
913     // check our enable status
914     if (!m_disabled && m_is_disabled) {
915         // this means that we are trying to enable
916         if (cycle == m_cycle_to_enable_at) {
917             m_is_disabled=false;
918             debugOutput(DEBUG_LEVEL_VERBOSE,"Enabling StreamProcessor %p at %d\n",
919                 this, cycle);
920                
921             // the previous timestamp is the one we need to start with
922             // because we're going to update the buffer again this loop
923             // using writeframes
924             m_data_buffer->setBufferTailTimestamp(m_last_timestamp2);
925
926         } else {
927             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
928                 "will enable StreamProcessor %p at %u, now is %d\n",
929                     this, m_cycle_to_enable_at, cycle);
930         }
931     } else if (m_disabled && !m_is_disabled) {
932         // trying to disable
933         debugOutput(DEBUG_LEVEL_VERBOSE,"disabling StreamProcessor %p at %u\n", this, cycle);
934         m_is_disabled=true;
935     }
936        
937         // If the packet length is 8 bytes (ie: just a CIP-like header)
938         // there is no isodata.
939         if (length > 8) {
940                 // The iso data blocks from the MOTUs comprise a CIP-like
941                 // header followed by a number of events (8 for 1x rates, 16
942                 // for 2x rates, 32 for 4x rates).
943                 quadlet_t *quadlet = (quadlet_t *)data;
944                 unsigned int dbs = get_bits(ntohl(quadlet[0]), 23, 8);  // Size of one event in terms of fdf_size
945                 unsigned int fdf_size = get_bits(ntohl(quadlet[1]), 23, 8) == 0x22 ? 32:0; // Event unit size in bits
946
947                 // Don't even attempt to process a packet if it isn't what
948                 // we expect from a MOTU.  Yes, an FDF value of 32 bears
949                 // little relationship to the actual data (24 bit integer)
950                 // sent by the MOTU - it's one of those areas where MOTU
951                 // have taken a curious detour around the standards.
952                 if (tag!=1 || fdf_size!=32) {
953                         return RAW1394_ISO_OK;
954                 }
955                
956                 // put this after the check because event_length can become 0 on invalid packets
957                 unsigned int event_length = (fdf_size * dbs) / 8;       // Event size in bytes
958                 unsigned int n_events = (length-8) / event_length;
959                
960         //=> store the previous timestamp
961         m_last_timestamp2=m_last_timestamp;
962
963         //=> convert the SYT to a full timestamp in ticks
964 //        m_last_timestamp=sytRecvToFullTicks((uint32_t)ntohl(*(quadlet_t *)(data+8)),
965 //                                        cycle, m_handler->getCycleTimer());
966 //***
967 // FIXME: it given that we later advance this to be the timestamp of the sample immediately following
968 // this packet, it perhaps makes more sense to acquire the timestamp of the last frame in the packet.
969 // Then it's just a matter of adding m_ticks_per_frame rather than frame_size times this.
970 uint32_t first_sph = ntohl(*(quadlet_t *)(data+8));
971 //        m_last_timestamp = ((first_sph & 0x1fff000)>>12)*3072 + (first_sph & 0xfff);
972         m_last_timestamp = CYCLE_TIMER_TO_TICKS(first_sph & 0x1ffffff);
973
974                 // Signal that we're running
975         if(!m_running && n_events && m_last_timestamp2 && m_last_timestamp) {
976             debugOutput(DEBUG_LEVEL_VERBOSE,"Receive StreamProcessor %p started running at %d\n", this, cycle);
977             m_running=true;
978         }
979
980         //=> don't process the stream samples when it is not enabled.
981         if(m_is_disabled) {
982
983             // we keep track of the timestamp here
984             // this makes sure that we will have a somewhat accurate
985             // estimate as to when a period might be ready. i.e. it will not
986             // be ready earlier than this timestamp + period time
987            
988             // the next (possible) sample is not this one, but lies
989             // SYT_INTERVAL * rate later
990             float frame_size=m_framerate<=48000?8:(m_framerate<=96000?16:32);
991             uint64_t ts=addTicks(m_last_timestamp,
992                                  (uint64_t)(frame_size * m_ticks_per_frame));
993
994             // set the timestamp as if there will be a sample put into
995             // the buffer by the next packet.
996             m_data_buffer->setBufferTailTimestamp(ts);
997            
998             return RAW1394_ISO_DEFER;
999         }
1000
1001                 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "put packet...\n");
1002
1003         //=> process the packet
1004         // add the data payload to the ringbuffer
1005         if(m_data_buffer->writeFrames(n_events, (char *)(data+8), m_last_timestamp)) {
1006             retval=RAW1394_ISO_OK;
1007            
1008             int dbc = get_bits(ntohl(quadlet[0]), 8, 8);
1009            
1010             // process all ports that should be handled on a per-packet base
1011             // this is MIDI for AMDTP (due to the need of DBC)
1012             if (!decodePacketPorts((quadlet_t *)(data+8), n_events, dbc)) {
1013                 debugWarning("Problem decoding Packet Ports\n");
1014                 retval=RAW1394_ISO_DEFER;
1015             }
1016            
1017         } else {
1018        
1019             debugWarning("Receive buffer overrun (cycle %d, FC=%d, PC=%d)\n",
1020                  cycle, m_data_buffer->getFrameCounter(), m_handler->getPacketCount());
1021            
1022             m_xruns++;
1023            
1024             // disable the processing, will be re-enabled when
1025             // the xrun is handled
1026             m_disabled=true;
1027             m_is_disabled=true;
1028
1029             retval=RAW1394_ISO_DEFER;
1030         }
1031     }
1032
1033         return retval;
1034 }
1035
1036 // returns the delay between the actual (real) time of a timestamp as received,
1037 // and the timestamp that is passed on for the same event. This is to cope with
1038 // ISO buffering
1039 int MotuReceiveStreamProcessor::getMinimalSyncDelay() {
1040         unsigned int n_events = m_framerate<=48000?8:(m_framerate<=96000?16:32);
1041    
1042     return (int)(m_handler->getWakeupInterval() * n_events * m_ticks_per_frame);
1043 }
1044
1045 bool MotuReceiveStreamProcessor::reset() {
1046
1047         debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n");
1048        
1049     // this makes that the buffer lags a little compared to reality
1050     // the result is that we get some extra time before period boundaries
1051     // are signaled.
1052     // ISO buffering causes the packets to be received at max
1053     // m_handler->getWakeupInterval() later than the time they were received.
1054     // hence their payload is available this amount of time later. However, the
1055     // period boundary is predicted based upon earlier samples, and therefore can
1056     // pass before these packets are processed. Adding this extra term makes that
1057     // the period boundary is signalled later
1058     m_data_buffer->setTickOffset(m_SyncSource->getSyncDelay());
1059
1060         // reset all non-device specific stuff
1061         // i.e. the iso stream and the associated ports
1062         if(!ReceiveStreamProcessor::reset()) {
1063                 debugFatal("Could not do base class reset\n");
1064                 return false;
1065         }
1066
1067         return true;
1068 }
1069
1070 bool MotuReceiveStreamProcessor::prepare() {
1071
1072         // prepare all non-device specific stuff
1073         // i.e. the iso stream and the associated ports
1074         if(!ReceiveStreamProcessor::prepare()) {
1075                 debugFatal("Could not prepare base class\n");
1076                 return false;
1077         }
1078
1079         debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing...\n");
1080
1081         m_PeriodStat.setName("RCV PERIOD");
1082         m_PacketStat.setName("RCV PACKET");
1083         m_WakeupStat.setName("RCV WAKEUP");
1084
1085     // setup any specific stuff here
1086     // FIXME: m_frame_size would be a better name
1087         debugOutput( DEBUG_LEVEL_VERBOSE, "Event size: %d\n", m_event_size);
1088    
1089     // prepare the framerate estimate
1090     float ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_framerate);
1091        
1092         // initialize internal buffer
1093         unsigned int ringbuffer_size_frames=m_nb_buffers * m_period;
1094        
1095         unsigned int events_per_frame = m_framerate<=48000?8:(m_framerate<=96000?16:32);
1096
1097     assert(m_data_buffer);   
1098     m_data_buffer->setBufferSize(ringbuffer_size_frames);
1099     m_data_buffer->setEventSize(m_event_size/events_per_frame);
1100     m_data_buffer->setEventsPerFrame(events_per_frame);
1101    
1102     m_data_buffer->setUpdatePeriod(m_period);
1103     m_data_buffer->setNominalRate(ticks_per_frame);
1104    
1105     m_data_buffer->setWrapValue(TICKS_PER_SECOND);
1106    
1107     m_data_buffer->prepare();
1108
1109         // set the parameters of ports we can:
1110         // we want the audio ports to be period buffered,
1111         // and the midi ports to be packet buffered
1112         for ( PortVectorIterator it = m_Ports.begin();
1113                   it != m_Ports.end();
1114                   ++it )
1115         {
1116                 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
1117                
1118                 if(!(*it)->setBufferSize(m_period)) {
1119                         debugFatal("Could not set buffer size to %d\n",m_period);
1120                         return false;
1121                 }
1122
1123                 switch ((*it)->getPortType()) {
1124                         case Port::E_Audio:
1125                                 if(!(*it)->setSignalType(Port::E_PeriodSignalled)) {
1126                                         debugFatal("Could not set signal type to PeriodSignalling");
1127                                         return false;
1128                                 }
1129                                 break;
1130                         case Port::E_Midi:
1131                                 if(!(*it)->setSignalType(Port::E_PacketSignalled)) {
1132                                         debugFatal("Could not set signal type to PacketSignalling");
1133                                         return false;
1134                                 }
1135                                 if (!(*it)->setBufferType(Port::E_RingBuffer)) {
1136                                         debugFatal("Could not set buffer type");
1137                                         return false;
1138                                 }
1139                                 if (!(*it)->setDataType(Port::E_MidiEvent)) {
1140                                         debugFatal("Could not set data type");
1141                                         return false;
1142                                 }
1143                                 // FIXME: probably need rate control too.  See
1144                                 // Port::useRateControl() and AmdtpStreamProcessor.
1145                                 break;
1146                         case Port::E_Control:
1147                                 if(!(*it)->setSignalType(Port::E_PeriodSignalled)) {
1148                                         debugFatal("Could not set signal type to PeriodSignalling");
1149                                         return false;
1150                                 }
1151                                 break;
1152                         default:
1153                                 debugWarning("Unsupported port type specified\n");
1154                                 break;
1155                 }
1156
1157         }
1158
1159         // The API specific settings of the ports are already set before
1160         // this routine is called, therefore we can init&prepare the ports
1161         if(!initPorts()) {
1162                 debugFatal("Could not initialize ports!\n");
1163                 return false;
1164         }
1165
1166         if(!preparePorts()) {
1167                 debugFatal("Could not initialize ports!\n");
1168                 return false;
1169         }
1170        
1171         return true;
1172
1173 }
1174
1175
1176 bool MotuReceiveStreamProcessor::prepareForStop() {
1177
1178         // A MOTU receive stream can stop at any time.  However, signify
1179         // that stopping is in progress because other streams (notably the
1180         // transmit stream) may keep going for some time and cause an
1181         // overflow in the receive buffers.  If a closedown is in progress
1182         // the receive handler simply throws all incoming data away so
1183         // no buffer overflow can occur.
1184         m_closedown_active = 1;
1185         return true;
1186 }
1187
1188 bool MotuReceiveStreamProcessor::prepareForStart() {
1189 // Reset some critical variables required so the stream starts cleanly. This
1190 // method is called once on every stream restart, including those during
1191 // xrun recovery.  Initialisations which should be done once should be
1192 // placed in the init() method instead.
1193         m_running = 0;
1194         m_closedown_active = 0;
1195
1196         // At this point we'll also disable the stream processor here.
1197         // At this stage stream processors are always explicitly re-enabled
1198         // after being started, so by starting in the disabled state we
1199         // ensure that every start will be exactly the same.
1200         disable();
1201
1202         return true;
1203 }
1204
1205 bool MotuReceiveStreamProcessor::getFrames(unsigned int nbframes) {
1206
1207     m_PeriodStat.mark(m_data_buffer->getBufferFill());
1208
1209     // ask the buffer to process nbframes of frames
1210     // using it's registered client's processReadBlock(),
1211     // which should be ours
1212     m_data_buffer->blockProcessReadFrames(nbframes);
1213
1214     return true;
1215 }
1216
1217 /**
1218  * \brief write received events to the port ringbuffers.
1219  */
1220 bool MotuReceiveStreamProcessor::processReadBlock(char *data,
1221                                            unsigned int nevents, unsigned int offset)
1222 {
1223         bool no_problem=true;
1224         for ( PortVectorIterator it = m_PeriodPorts.begin();
1225           it != m_PeriodPorts.end();
1226           ++it ) {
1227                 if((*it)->isDisabled()) {continue;};
1228
1229                 //FIXME: make this into a static_cast when not DEBUG?
1230                 Port *port=dynamic_cast<Port *>(*it);
1231                
1232                 switch(port->getPortType()) {
1233                
1234                 case Port::E_Audio:
1235                         if(decodeMotuEventsToPort(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
1236                                 debugWarning("Could not decode packet MBLA to port %s",(*it)->getName().c_str());
1237                                 no_problem=false;
1238                         }
1239                         break;
1240                 // midi is a packet based port, don't process
1241                 //      case MotuPortInfo::E_Midi:
1242                 //              break;
1243
1244                 default: // ignore
1245                         break;
1246                 }
1247         }
1248         return no_problem;
1249 }
1250
1251 /**
1252  * @brief decode a packet for the packet-based ports
1253  *
1254  * @param data Packet data
1255  * @param nevents number of events in data (including events of other ports & port types)
1256  * @param dbc DataBlockCount value for this packet
1257  * @return true if all successfull
1258  */
1259 bool MotuReceiveStreamProcessor::decodePacketPorts(quadlet_t *data, unsigned int nevents,
1260                 unsigned int dbc) {
1261         bool ok=true;
1262
1263         // Use char here since the source address won't necessarily be
1264         // aligned; use of an unaligned quadlet_t may cause issues on
1265         // certain architectures.  Besides, the source for MIDI data going
1266         // directly to the MOTU isn't structured in quadlets anyway; it is a
1267         // sequence of 3 unaligned bytes.
1268         unsigned char *src = NULL;
1269
1270         for ( PortVectorIterator it = m_PacketPorts.begin();
1271                 it != m_PacketPorts.end();
1272                 ++it ) {
1273
1274                 Port *port=dynamic_cast<Port *>(*it);
1275                 assert(port); // this should not fail!!
1276
1277                 // Currently the only packet type of events for MOTU
1278                 // is MIDI in mbla.  However in future control data
1279                 // might also be sent via "packet" events, so allow
1280                 // for this possible expansion.
1281
1282                 // FIXME: MIDI input is completely untested at present.
1283                 switch (port->getPortType()) {
1284                         case Port::E_Midi: {
1285                                 MotuMidiPort *mp=static_cast<MotuMidiPort *>(*it);
1286                                 signed int sample;
1287                                 unsigned int j = 0;
1288                                 // Get MIDI bytes if present anywhere in the
1289                                 // packet.  MOTU MIDI data is sent using a
1290                                 // 3-byte sequence starting at the port's
1291                                 // position.  It's thought that there can never
1292                                 // be more than one MIDI byte per packet, but
1293                                 // for completeness we'll check the entire packet
1294                                 // anyway.
1295                                 src = (unsigned char *)data + mp->getPosition();
1296                                 while (j < nevents) {
1297                                         if (*src==0x01 && *(src+1)==0x00) {
1298                                                 sample = *(src+2);
1299                                                 if (!mp->writeEvent(&sample)) {
1300                                                         debugWarning("MIDI packet port events lost\n");
1301                                                         ok = false;
1302                                                 }
1303                                         }
1304                                         j++;
1305                                         src += m_event_size;
1306                                 }
1307                                 break;
1308                         }
1309                         default:
1310                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown packet-type port format %d\n",port->getPortType());
1311                                 return ok;       
1312                 }
1313         }
1314
1315         return ok;
1316 }
1317
1318 signed int MotuReceiveStreamProcessor::decodeMotuEventsToPort(MotuAudioPort *p,
1319                 quadlet_t *data, unsigned int offset, unsigned int nevents)
1320 {
1321         unsigned int j=0;
1322
1323         // Use char here since a port's source address won't necessarily be
1324         // aligned; use of an unaligned quadlet_t may cause issues on
1325         // certain architectures.  Besides, the source (data coming directly
1326         // from the MOTU) isn't structured in quadlets anyway; it mainly
1327         // consists of packed 24-bit integers.
1328
1329         unsigned char *src_data;
1330         src_data = (unsigned char *)data + p->getPosition();
1331
1332         switch(p->getDataType()) {
1333                 default:
1334                 case Port::E_Int24:
1335                         {
1336                                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
1337
1338                                 assert(nevents + offset <= p->getBufferSize());
1339
1340                                 // Offset is in frames, but each port is only a single
1341                                 // channel, so the number of frames is the same as the
1342                                 // number of quadlets to offset (assuming the port buffer
1343                                 // uses one quadlet per sample, which is the case currently).
1344                                 buffer+=offset;
1345
1346                                 for(j = 0; j < nevents; j += 1) { // Decode nsamples
1347                                         *buffer = (*src_data<<16)+(*(src_data+1)<<8)+*(src_data+2);
1348                                         // Sign-extend highest bit of 24-bit int.
1349                                         // FIXME: this isn't strictly needed since E_Int24 is a 24-bit,
1350                                         // but doing so shouldn't break anything and makes the data
1351                                         // easier to deal with during debugging.
1352                                         if (*src_data & 0x80)
1353                                                 *buffer |= 0xff000000;
1354
1355                                         buffer++;
1356                                         src_data+=m_event_size;
1357                                 }
1358                         }
1359                         break;
1360                 case Port::E_Float:
1361                         {
1362                                 const float multiplier = 1.0f / (float)(0x7FFFFF);
1363                                 float *buffer=(float *)(p->getBufferAddress());
1364
1365                                 assert(nevents + offset <= p->getBufferSize());
1366
1367                                 buffer+=offset;
1368
1369                                 for(j = 0; j < nevents; j += 1) { // decode max nsamples               
1370        
1371                                         unsigned int v = (*src_data<<16)+(*(src_data+1)<<8)+*(src_data+2);
1372
1373                                         // sign-extend highest bit of 24-bit int
1374                                         int tmp = (int)(v << 8) / 256;
1375                
1376                                         *buffer = tmp * multiplier;
1377                                
1378                                         buffer++;
1379                                         src_data+=m_event_size;
1380                                 }
1381                         }
1382                         break;
1383         }
1384
1385         return 0;
1386 }
1387
1388 signed int MotuReceiveStreamProcessor::setEventSize(unsigned int size) {
1389         m_event_size = size;
1390         return 0;
1391 }
1392
1393 unsigned int MotuReceiveStreamProcessor::getEventSize(void) {
1394 //
1395 // Return the size of a single event sent by the MOTU as part of an iso
1396 // data packet in bytes.
1397 //
1398         return m_event_size;
1399 }
1400
1401 void MotuReceiveStreamProcessor::setVerboseLevel(int l) {
1402         setDebugLevel(l);
1403         ReceiveStreamProcessor::setVerboseLevel(l);
1404 }
1405
1406 } // end of namespace FreebobStreaming
Note: See TracBrowser for help on using the browser.