root/branches/libfreebob-2.0/src/libstreaming/MotuStreamProcessor.cpp

Revision 312, 48.7 kB (checked in by jwoithe, 16 years ago)

MOTU: fix xrun recovery glitches inadvertantly introduced in r309.
MOTU: preliminary MIDI port support. Rate control still needs to be added so it probably won't work in its current form yet. MIDI has not yet been tested.
MOTU: tweaks to receive/transmit missed cycle detection.
jack driver: during driver shutdown don't try to free NULL ports created for non-audio ports during initialisation to preserve device port index locations.

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
30
31 #include "MotuStreamProcessor.h"
32 #include "Port.h"
33 #include "MotuPort.h"
34
35 #include <math.h>
36
37 #include <netinet/in.h>
38
39 namespace FreebobStreaming {
40
41 IMPL_DEBUG_MODULE( MotuTransmitStreamProcessor, MotuTransmitStreamProcessor, DEBUG_LEVEL_NORMAL );
42 IMPL_DEBUG_MODULE( MotuReceiveStreamProcessor, MotuReceiveStreamProcessor, DEBUG_LEVEL_NORMAL );
43
44 // Set to 1 to enable the generation of a 1 kHz test tone in analog output 1
45 #define TESTTONE 1
46
47 // A macro to extract specific bits from a native endian quadlet
48 #define get_bits(_d,_start,_len) (((_d)>>((_start)-(_len)+1)) & ((1<<(_len))-1))
49
50 /* transmit */
51 MotuTransmitStreamProcessor::MotuTransmitStreamProcessor(int port, int framerate,
52                 unsigned int event_size)
53         : TransmitStreamProcessor(port, framerate), m_event_size(event_size),
54         m_tx_dbc(0), m_cycle_count(-1), m_cycle_ofs(0.0), m_next_cycle(-1),
55         m_ticks_per_frame(NULL), m_closedown_count(-1), m_streaming_active(0) {
56 }
57
58 MotuTransmitStreamProcessor::~MotuTransmitStreamProcessor() {
59         freebob_ringbuffer_free(m_event_buffer);
60         free(m_tmp_event_buffer);
61 }
62
63 bool MotuTransmitStreamProcessor::init() {
64
65         debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing (%p)...\n");
66         // call the parent init
67         // this has to be done before allocating the buffers,
68         // because this sets the buffersizes from the processormanager
69         if(!TransmitStreamProcessor::init()) {
70                 debugFatal("Could not do base class init (%p)\n",this);
71                 return false;
72         }
73
74         return true;
75 }
76
77 void MotuTransmitStreamProcessor::setVerboseLevel(int l) {
78         setDebugLevel(l); // sets the debug level of the current object
79         TransmitStreamProcessor::setVerboseLevel(l); // also set the level of the base class
80 }
81
82
83 enum raw1394_iso_disposition
84 MotuTransmitStreamProcessor::getPacket(unsigned char *data, unsigned int *length,
85                       unsigned char *tag, unsigned char *sy,
86                       int cycle, unsigned int dropped, unsigned int max_length) {
87
88 // FIXME: the actual delays in the system need to be worked out so
89 // we can get this thing synchronised.  For now this seems to work.
90 #define CYCLE_DELAY 1
91
92         enum raw1394_iso_disposition retval = RAW1394_ISO_OK;
93         quadlet_t *quadlet = (quadlet_t *)data;
94         signed int i;
95         signed int unwrapped_cycle = cycle;
96
97         // Signal that streaming is still active
98         m_streaming_active = 1;
99
100         // The MOTU transmit stream is 'always' ready
101         m_running = true;
102        
103         // Initialise the cycle counter if this is the first time
104         // iso data has been requested.
105         if (!m_disabled && m_cycle_count<0) {
106                 m_cycle_count = cycle;
107                 m_cycle_ofs = 0.0;
108         }
109
110         // Similarly, initialise the "next cycle".  This can be done
111         // whenever iso data is seen - it doesn't have to wait until
112         // the stream is enabled.
113         if (m_next_cycle < 0)
114                 m_next_cycle = cycle;
115
116         // Do housekeeping expected for all packets sent to the MOTU, even
117         // for packets containing no audio data.
118         *sy = 0x00;
119         *tag = 1;      // All MOTU packets have a CIP-like header
120
121         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "get packet...\n");
122
123         // Size of a single data frame in quadlets
124         unsigned dbs = m_event_size / 4;
125
126         // The number of events expected by the MOTU is solely dependent on
127         // the current sample rate.  An 'event' is one sample from all channels
128         // plus possibly other midi and control data.
129         signed n_events = m_framerate<=48000?8:(m_framerate<=96000?16:32);
130
131         // Size of data to read from the event buffer, in bytes.
132         unsigned int read_size = n_events * m_event_size;
133
134         // Detect a missed cycle and attempt to "catch up".
135         if (cycle != m_next_cycle) {
136                 debugOutput(DEBUG_LEVEL_VERBOSE, "tx cycle miss: %d requested, %d expected\n",cycle,m_next_cycle);
137         }
138         // Attempt to catch up any missed cycles but only if we're enabled.
139         if (!m_disabled && cycle!=m_next_cycle) {
140                 float ftmp;
141                 signed int ccount = m_next_cycle;
142
143                 while (ccount!=cycle) {
144                         unwrapped_cycle = ccount;
145                         if (m_cycle_count-ccount > 7900)
146                                 unwrapped_cycle += 8000;
147
148                         if (unwrapped_cycle < m_cycle_count) {
149                                 if (++ccount == 8000)
150                                         ccount = 0;
151                                 continue;
152                         }
153                         // Advance buffers and counters as if this cycle had been dealt with
154                         m_tx_dbc += n_events;
155                         incrementFrameCounter(n_events);
156
157                         ftmp = m_cycle_ofs+n_events*(*m_ticks_per_frame);
158                         m_cycle_count += (unsigned int)ftmp/3072;
159                         m_cycle_count %= 8000;
160                         m_cycle_ofs = fmod(ftmp, 3072);
161
162                         if (++ccount == 8000)
163                                 ccount = 0;
164
165                         // Also advance the event buffer to keep things in sync
166                         freebob_ringbuffer_read_advance(m_event_buffer,read_size);
167                 }
168                 m_tx_dbc &= 0xff;
169                 debugOutput(DEBUG_LEVEL_VERBOSE, "  resuming with cyclecount=%d, cycleofs=%g (ticksperfame=%g)\n",
170                         m_cycle_count, m_cycle_ofs, *m_ticks_per_frame);
171
172                 m_next_cycle = cycle;
173         }
174
175         if ((m_next_cycle=cycle+1) >= 8000)
176                 m_next_cycle -= 8000;
177
178         // Deal cleanly with potential wrap-around cycle counter conditions
179         unwrapped_cycle = cycle;
180         if (m_cycle_count-cycle > 7900)
181                 unwrapped_cycle += 8000;
182
183         // Increment the dbc (data block count).  This is only done if the
184         // packet will contain events - that is, we are due to send some
185         // data.  Otherwise a pad packet is sent which contains the DBC of
186         // the previously sent packet.  This regime also means that the very
187         // first packet containing data will have a DBC of n_events, which
188         // matches what is observed from other systems.
189         if (!m_disabled && unwrapped_cycle>=m_cycle_count) {
190                 m_tx_dbc += n_events;
191                 if (m_tx_dbc > 0xff)
192                         m_tx_dbc -= 0x100;
193         }
194
195         // construct the packet CIP-like header.  Even if this is a data-less
196         // packet the dbs field is still set as if there were data blocks
197         // present.  For data-less packets the dbc is the same as the previously
198         // transmitted block.
199         *quadlet = htonl(0x00000400 | ((getNodeId()&0x3f)<<24) | m_tx_dbc | (dbs<<16));
200         quadlet++;
201         *quadlet = htonl(0x8222ffff);
202         quadlet++;
203         *length = 8;
204
205         // If the stream is disabled or the MOTU transmission cycle count is
206         // ahead of the ieee1394 cycle timer, we send a data-less packet
207         // with only the 8 byte CIP-like header set up previously.
208         if (m_disabled || unwrapped_cycle<m_cycle_count) {
209                 return RAW1394_ISO_OK;
210         }
211
212         // In the disabled state simply zero all data sent to the MOTU.  If
213         // a stream of empty packets are sent once iso streaming is enabled
214         // the MOTU tends to emit high-pitched audio (approx 10 kHz) for
215         // some reason.  This is not completely sufficient, however (zeroed
216         // packets must also be sent on iso closedown).
217
218         // FIXME: Currently we simply send empty packets to the MOTU when
219         // the stream is disabled so the "m_disabled == 0" code is never
220         // executed.  However, this may change in future so it's left in
221         // for the moment for reference.
222         // FIXME: Currently we don't read the buffer at all during closedown.
223         // We could (and silently junk the contents) if it turned out to be
224         // more helpful.
225         if (!m_disabled && m_closedown_count<0) {
226                 // We read the packet data from a ringbuffer because of
227                 // efficiency; it allows us to construct the packets one
228                 // period at once.
229                 i = freebob_ringbuffer_read(m_event_buffer,(char *)(data+8),read_size) <
230                         read_size;
231         } else {
232                 memset(data+8, 0, read_size);
233                 i = 0;
234         }
235         if (i == 1) {
236                 /* there is no more data in the ringbuffer */
237                 debugWarning("Transmit buffer underrun (cycle %d, FC=%d, PC=%d)\n",
238                         cycle, m_framecounter, m_handler->getPacketCount());
239
240                 // signal underrun
241                 m_xruns++;
242
243                 retval=RAW1394_ISO_DEFER; // make raw1394_loop_iterate exit its inner loop
244                 n_events = 0;
245
246         } else {
247
248                 retval=RAW1394_ISO_OK;
249                 *length += read_size;
250
251                 // FIXME: if we choose to read the buffer even during closedown,
252                 // here is where the data is silenced.
253                 //   if (m_closedown_count >= 0)
254                 //     memset(data+8, 0, read_size);
255                 if (m_closedown_count > 0)
256                         m_closedown_count--;
257
258                 // Set up each frames's SPH.  Note that the (int) typecast
259                 // appears to do rounding.
260                 //
261                 // CYCLE_DELAY accounts for the delay between the cycle
262                 // audio is sent in and when the MOTU can actually play
263                 // that audio.  The SPH timestamp must account for this
264                 // so it doesn't demand to be played before it's possible.
265                 // For the duration of the event loop, account for the
266                 // CYCLE_DELAY within m_cycle_count to save having to wrap
267                 // (m_cycle_count+CYCLE_DELAY) and m_cycle_count separately
268                 // within the event loop.  Once the loop is finished we
269                 // reset m_cyle_count to once again refer to the send
270                 // cycle rather than the audio presentation cycle.
271                 //
272                 // This seemingly messy treatment saves one modulo operation
273                 // per loop iteration.  Since the loop count ranges from 8
274                 // (for 1x sample rates) to 32 there are considerable
275                 // savings to be made even at 1x rates.
276                 if ((m_cycle_count+=CYCLE_DELAY) >= 8000)
277                         m_cycle_count -= 8000;
278                 for (i=0; i<n_events; i++, quadlet += dbs) {
279                         *quadlet = htonl( (m_cycle_count<<12) + (int)m_cycle_ofs);
280 #if TESTTONE
281                         // FIXME: remove this hacked in 1 kHz test signal to
282                         // analog-1 when testing is complete.  Note that the tone is
283                         // *never* added during closedown.
284                         if (m_closedown_count<0) {
285                                 static signed int a_cx = 0;
286                                 signed int val;
287                                 val = (int)(0x7fffff*sin(1000.0*2.0*M_PI*(a_cx/24576000.0)));
288                                 if ((a_cx+=512) >= 24576000) {
289                                         a_cx -= 24576000;
290                                 }
291                                 *(data+8+i*m_event_size+16) = (val >> 16) & 0xff;
292                                 *(data+8+i*m_event_size+17) = (val >> 8) & 0xff;
293                                 *(data+8+i*m_event_size+18) = val & 0xff;
294                         }
295 #endif
296                         if ((m_cycle_ofs+=*m_ticks_per_frame) >= 3072) {
297                                 m_cycle_ofs -= 3072;
298                                 if (++m_cycle_count > 7999)
299                                         m_cycle_count -= 8000;
300                         }
301                 }
302                 // Reset m_cycle_count to the send cycle
303                 if ((m_cycle_count-=CYCLE_DELAY) < 0)
304                         m_cycle_count += 8000;
305
306                 // Process all ports that should be handled on a per-packet base
307                 // this is MIDI for AMDTP (due to the need of DBC, which is lost
308                 // when putting the events in the ringbuffer)
309                 // for motu this might also be control data, however as control
310                 // data isn't time specific I would also include it in the period
311                 // based processing
312        
313                 // FIXME: m_tx_dbc probably needs to be initialised to a non-zero
314                 // value somehow so MIDI sync is possible.  For now we ignore
315                 // this issue.
316                 if (!encodePacketPorts((quadlet_t *)(data+8), n_events, m_tx_dbc)) {
317                         debugWarning("Problem encoding Packet Ports\n");
318                 }
319         }
320    
321         // Update the frame counter
322         incrementFrameCounter(n_events);
323
324         // Keep this at the end, because otherwise the raw1394_loop_iterate
325         // functions inner loop keeps requesting packets, that are not
326         // nescessarily ready
327
328 // Amdtp has this commented out
329         if (m_framecounter > (signed int)m_period) {
330                 retval=RAW1394_ISO_DEFER;
331         }
332        
333         return retval;
334 }
335
336 bool MotuTransmitStreamProcessor::isOnePeriodReady() {
337         // TODO: this is the way you can implement sync
338         //       only when this returns true, one period will be
339         //       transferred to the audio api side.
340         //       you can delay this moment as long as you
341         //       want (provided that there is enough buffer space)
342        
343         // this implementation just waits until there is one period of samples
344         // transmitted from the buffer
345
346 // Amdtp has this commented out and simply return true.
347         return (m_framecounter > (signed int)m_period);
348 //      return true;
349 }
350  
351 bool MotuTransmitStreamProcessor::prefill() {
352         // this is needed because otherwise there is no data to be
353         // sent when the streaming starts
354    
355         int i = m_nb_buffers;
356         while (i--) {
357                 if(!transferSilence(m_period)) {
358                         debugFatal("Could not prefill transmit stream\n");
359                         return false;
360                 }
361         }
362         return true;
363 }
364
365 bool MotuTransmitStreamProcessor::reset() {
366
367         debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n");
368
369         // reset the event buffer, discard all content
370         freebob_ringbuffer_reset(m_event_buffer);
371    
372         // reset all non-device specific stuff
373         // i.e. the iso stream and the associated ports
374         if (!TransmitStreamProcessor::reset()) {
375                 debugFatal("Could not do base class reset\n");
376                 return false;
377         }
378
379         // we should prefill the event buffer
380         if (!prefill()) {
381                 debugFatal("Could not prefill buffers\n");
382                 return false;   
383         }
384
385         return true;
386 }
387
388 bool MotuTransmitStreamProcessor::prepare() {
389    
390         debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing...\n");
391    
392         // prepare all non-device specific stuff
393         // i.e. the iso stream and the associated ports
394         if (!TransmitStreamProcessor::prepare()) {
395                 debugFatal("Could not prepare base class\n");
396                 return false;
397         }
398
399         m_PeriodStat.setName("XMT PERIOD");
400         m_PacketStat.setName("XMT PACKET");
401         m_WakeupStat.setName("XMT WAKEUP");
402
403         debugOutput( DEBUG_LEVEL_VERBOSE, "Event size: %d\n", m_event_size);
404    
405         // allocate the event buffer
406         unsigned int ringbuffer_size_frames=m_nb_buffers * m_period;
407    
408         if( !(m_event_buffer=freebob_ringbuffer_create(
409           m_event_size * ringbuffer_size_frames))) {
410                 debugFatal("Could not allocate memory event ringbuffer");
411                 return false;
412         }
413
414         // Allocate the temporary event buffer.  This is needed for the
415         // efficient transfer() routine.  Its size has to be equal to one
416         // 'event'.
417         if( !(m_tmp_event_buffer=(char *)calloc(1,m_event_size))) {
418                 debugFatal("Could not allocate temporary event buffer");
419                 freebob_ringbuffer_free(m_event_buffer);
420                 return false;
421         }
422
423         // Set the parameters of ports we can: we want the audio ports to be
424         // period buffered, and the midi ports to be packet buffered.
425         for ( PortVectorIterator it = m_Ports.begin();
426           it != m_Ports.end();
427           ++it ) {
428                 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
429                 if(!(*it)->setBufferSize(m_period)) {
430                         debugFatal("Could not set buffer size to %d\n",m_period);
431                         return false;
432                 }
433
434                 switch ((*it)->getPortType()) {
435                 case Port::E_Audio:
436                         if (!(*it)->setSignalType(Port::E_PeriodSignalled)) {
437                                 debugFatal("Could not set signal type to PeriodSignalling");
438                                 return false;
439                         }
440                         break;
441
442                 case Port::E_Midi:
443                         if (!(*it)->setSignalType(Port::E_PacketSignalled)) {
444                                 debugFatal("Could not set signal type to PacketSignalling");
445                                 return false;
446                         }
447                         if (!(*it)->setBufferType(Port::E_RingBuffer)) {
448                                 debugFatal("Could not set buffer type");
449                                 return false;
450                         }
451                         if (!(*it)->setDataType(Port::E_MidiEvent)) {
452                                 debugFatal("Could not set data type");
453                                 return false;
454                         }
455                         // FIXME: probably need rate control too.  See
456                         // Port::useRateControl() and AmdtpStreamProcessor.
457                         break;
458                
459                 case Port::E_Control:
460                         if (!(*it)->setSignalType(Port::E_PeriodSignalled)) {
461                                 debugFatal("Could not set signal type to PeriodSignalling");
462                                 return false;
463                         }
464                         break;
465
466                 default:
467                         debugWarning("Unsupported port type specified\n");
468                         break;
469                 }
470         }
471
472         // The API specific settings of the ports are already set before
473         // this routine is called, therefore we can init&prepare the ports
474         if (!initPorts()) {
475                 debugFatal("Could not initialize ports!\n");
476                 return false;
477         }
478
479         if(!preparePorts()) {
480                 debugFatal("Could not initialize ports!\n");
481                 return false;
482         }
483
484         // We should prefill the event buffer
485         if (!prefill()) {
486                 debugFatal("Could not prefill buffers\n");
487                 return false;   
488         }
489
490         return true;
491 }
492
493 bool MotuTransmitStreamProcessor::transferSilence(unsigned int size) {
494    
495         // This function should tranfer 'size' frames of 'silence' to the event buffer
496         unsigned int write_size=size*m_event_size;
497         char *dummybuffer=(char *)calloc(size,m_event_size);
498
499         transmitSilenceBlock(dummybuffer, size, 0);
500
501         if (freebob_ringbuffer_write(m_event_buffer,(char *)(dummybuffer),write_size) < write_size) {
502                 debugWarning("Could not write to event buffer\n");
503         }
504
505         free(dummybuffer);
506
507         return true;
508 }
509
510 /**
511  * \brief write events queued for transmission from the port ringbuffers
512  * to the event buffer.
513  */
514 bool MotuTransmitStreamProcessor::transfer() {
515         m_PeriodStat.mark(freebob_ringbuffer_read_space(m_event_buffer)/m_event_size);
516
517         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n");
518         // TODO: improve
519 /* a naive implementation would look like this:
520
521         unsigned int write_size=m_period*m_event_size;
522         char *dummybuffer=(char *)calloc(m_period,m_event_size);
523
524         transmitBlock(dummybuffer, m_period, 0, 0);
525
526         if (freebob_ringbuffer_write(m_event_buffer,(char *)(dummybuffer),write_size) < write_size) {
527                 debugWarning("Could not write to event buffer\n");
528         }
529
530         free(dummybuffer);
531 */
532 /* but we're not that naive anymore... */
533         int xrun;
534         unsigned int offset=0;
535
536         freebob_ringbuffer_data_t vec[2];
537         // There is one period of frames to transfer.  This is
538         // period_size*m_event_size of events.
539         unsigned int bytes2write=m_period*m_event_size;
540
541         /* Write bytes2write bytes to the event ringbuffer.  First see if it can
542          * be done in one write; if so, ok.
543          * Otherwise write up to a multiple of events directly to the buffer
544          * then do the buffer wrap around using ringbuffer_write.  Then
545          * write the remaining data directly to the buffer in a third pass.
546          * Make sure that we cannot end up on a non-cluster aligned
547          * position!
548          */
549         while(bytes2write>0) {
550                 int byteswritten=0;
551        
552                 unsigned int frameswritten=(m_period*m_event_size-bytes2write)/m_event_size;
553                 offset=frameswritten;
554
555                 freebob_ringbuffer_get_write_vector(m_event_buffer, vec);
556
557                 if (vec[0].len==0) { // this indicates a full event buffer
558                         debugError("XMT: Event buffer overrun in processor %p\n",this);
559                         break;
560                 }
561
562                 /* If we don't take care we will get stuck in an infinite
563                  * loop because we align to a event boundary later.  The
564                  * remaining nb of bytes in one write operation can be
565                  * smaller than one event; this can happen because the
566                  * ringbuffer size is always a power of 2.
567                  */
568                 if(vec[0].len<m_event_size) {
569            
570                         // encode to the temporary buffer
571                         xrun = transmitBlock(m_tmp_event_buffer, 1, offset);
572            
573                         if (xrun<0) {
574                                 // xrun detected
575                                 debugError("XMT: Frame buffer underrun in processor %p\n",this);
576                                 break;
577                         }
578
579                         // Use the ringbuffer function to write one event.
580                         // The write function handles the wrap around.
581                         freebob_ringbuffer_write(m_event_buffer,
582                                 m_tmp_event_buffer, m_event_size);
583                
584                         // we advanced one m_event_size
585                         bytes2write-=m_event_size;
586                
587                 } else {
588            
589                         if (bytes2write>vec[0].len) {
590                                 // align to an event boundary
591                                 byteswritten=vec[0].len-(vec[0].len%m_event_size);
592                         } else {
593                                 byteswritten=bytes2write;
594                         }
595
596                         xrun = transmitBlock(vec[0].buf,
597                                 byteswritten/m_event_size, offset);
598            
599                         if (xrun<0) {
600                                 // xrun detected
601                                 debugError("XMT: Frame buffer underrun in processor %p\n",this);
602                                 break;
603                         }
604
605                         freebob_ringbuffer_write_advance(m_event_buffer, byteswritten);
606                         bytes2write -= byteswritten;
607                 }
608
609                 // the bytes2write should always be event aligned
610                 assert(bytes2write%m_event_size==0);
611         }
612
613         return true;
614 }
615 /*
616  * write received events to the stream ringbuffers.
617  */
618
619 int MotuTransmitStreamProcessor::transmitBlock(char *data,
620                        unsigned int nevents, unsigned int offset) {
621         signed int problem=0;
622         unsigned int i;
623
624         // FIXME: ensure the MIDI and control streams are all zeroed until
625         // such time as they are fully implemented.
626         for (i=0; i<nevents; i++) {
627                 memset(data+4+i*m_event_size, 0x00, 6);
628         }
629
630         for ( PortVectorIterator it = m_PeriodPorts.begin();
631           it != m_PeriodPorts.end();
632           ++it ) {
633                 // If this port is disabled, don't process it
634                 if((*it)->isDisabled()) {continue;};
635        
636                 //FIXME: make this into a static_cast when not DEBUG?
637                 Port *port=dynamic_cast<Port *>(*it);
638                
639                 switch(port->getPortType()) {
640                
641                 case Port::E_Audio:
642                         if (encodePortToMBLAEvents(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
643                                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str());
644                                 problem=1;
645                         }
646                         break;
647                 // midi is a packet based port, don't process
648                 //      case MotuPortInfo::E_Midi:
649                 //              break;
650
651                 default: // ignore
652                         break;
653                 }
654         }
655         return problem;
656 }
657
658 int MotuTransmitStreamProcessor::transmitSilenceBlock(char *data,
659                        unsigned int nevents, unsigned int offset) {
660         // This is the same as the non-silence version, except that is
661         // doesn't read from the port buffers.
662
663         int problem=0;
664
665         for ( PortVectorIterator it = m_PeriodPorts.begin();
666           it != m_PeriodPorts.end();
667           ++it ) {
668                 //FIXME: make this into a static_cast when not DEBUG?
669                 Port *port=dynamic_cast<Port *>(*it);
670                
671                 switch(port->getPortType()) {
672                
673                 case Port::E_Audio:
674                         if (encodeSilencePortToMBLAEvents(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
675                                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str());
676                                 problem=1;
677                         }
678                         break;
679                 // midi is a packet based port, don't process
680                 //      case MotuPortInfo::E_Midi:
681                 //              break;
682
683                 default: // ignore
684                         break;
685                 }
686         }
687         return problem;
688 }
689
690 /**
691  * @brief decode a packet for the packet-based ports
692  *
693  * @param data Packet data
694  * @param nevents number of events in data (including events of other ports & port types)
695  * @param dbc DataBlockCount value for this packet
696  * @return true if all successfull
697  */
698 bool MotuTransmitStreamProcessor::encodePacketPorts(quadlet_t *data, unsigned int nevents,
699                 unsigned int dbc) {
700         bool ok=true;
701         char byte;
702
703         // Use char here since the target address won't necessarily be
704         // aligned; use of an unaligned quadlet_t may cause issues on
705         // certain architectures.  Besides, the target for MIDI data going
706         // directly to the MOTU isn't structured in quadlets anyway; it is a
707         // sequence of 3 unaligned bytes.
708         unsigned char *target = NULL;
709
710         for ( PortVectorIterator it = m_PacketPorts.begin();
711                 it != m_PacketPorts.end();
712                 ++it ) {
713
714 #ifdef DEBUG
715                 //FIXME: make this into a static_cast when not DEBUG?
716                 Port *port=dynamic_cast<Port *>(*it);
717                 assert(port); // this should not fail!!
718
719                 // Currently the only packet type of events for MOTU
720                 // is MIDI in mbla.  However in future control data
721                 // might also be sent via "packet" events.
722                 // assert(pinfo->getFormat()==MotuPortInfo::E_Midi);
723 #endif
724                 // FIXME: MIDI output is completely untested at present.
725                 switch (port->getPortType()) {
726                         case Port::E_Midi: {
727                                 MotuMidiPort *mp=static_cast<MotuMidiPort *>(*it);
728
729                                 // Send a byte if we can. MOTU MIDI data is
730                                 // sent using a 3-byte sequence starting at
731                                 // the port's position.  For now we'll
732                                 // always send in the first event of a
733                                 // packet, but this might need refinement
734                                 // later.
735                                 if (mp->canRead()) {
736                                         mp->readEvent(&byte);
737                                         target = (unsigned char *)data + mp->getPosition();
738                                         *(target++) = 0x01;
739                                         *(target++) = 0x00;
740                                         *(target++) = byte;
741                                 }
742                                 break;
743                         }
744                         default:
745                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown packet-type port type %d\n",port->getPortType());
746                                 return ok;       
747                 }
748         }
749
750         return ok;
751 }
752
753 int MotuTransmitStreamProcessor::encodePortToMBLAEvents(MotuAudioPort *p, quadlet_t *data,
754                        unsigned int offset, unsigned int nevents) {
755 // Encodes nevents worth of data from the given port into the given buffer.  The
756 // format of the buffer is precisely that which will be sent to the MOTU.
757 // The basic idea:
758 //   iterate over the ports
759 //     * get port buffer address
760 //     * loop over events
761 //         - pick right sample in event based upon PortInfo
762 //         - convert sample from Port format (E_Int24, E_Float, ..) to MOTU
763 //           native format
764 //
765 // We include the ability to start the transfer from the given offset within
766 // the port (expressed in frames) so the 'efficient' transfer method can be
767 // utilised.
768
769         unsigned int j=0;
770
771         // Use char here since the target address won't necessarily be
772         // aligned; use of an unaligned quadlet_t may cause issues on certain
773         // architectures.  Besides, the target (data going directly to the MOTU)
774         // isn't structured in quadlets anyway; it mainly consists of packed
775         // 24-bit integers.
776         unsigned char *target;
777         target = (unsigned char *)data + p->getPosition();
778
779         switch(p->getDataType()) {
780                 default:
781                 case Port::E_Int24:
782                         {
783                                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
784
785                                 assert(nevents + offset <= p->getBufferSize());
786
787                                 // Offset is in frames, but each port is only a single
788                                 // channel, so the number of frames is the same as the
789                                 // number of quadlets to offset (assuming the port buffer
790                                 // uses one quadlet per sample, which is the case currently).
791                                 buffer+=offset;
792
793                                 for(j = 0; j < nevents; j += 1) { // Decode nsamples
794                                         *target = (*buffer >> 16) & 0xff;
795                                         *(target+1) = (*buffer >> 8) & 0xff;
796                                         *(target+2) = (*buffer) & 0xff;
797
798                                         buffer++;
799                                         target+=m_event_size;
800                                 }
801                         }
802                         break;
803                 case Port::E_Float:
804                         {
805                                 const float multiplier = (float)(0x7FFFFF);
806                                 float *buffer=(float *)(p->getBufferAddress());
807
808                                 assert(nevents + offset <= p->getBufferSize());
809
810                                 buffer+=offset;
811
812                                 for(j = 0; j < nevents; j += 1) { // decode max nsamples               
813                                         unsigned int v = (int)(*buffer * multiplier);
814                                         *target = (v >> 16) & 0xff;
815                                         *(target+1) = (v >> 8) & 0xff;
816                                         *(target+2) = v & 0xff;
817
818                                         buffer++;
819                                         target+=m_event_size;
820                                 }
821                         }
822                         break;
823         }
824
825         return 0;
826 }
827
828 int MotuTransmitStreamProcessor::encodeSilencePortToMBLAEvents(MotuAudioPort *p, quadlet_t *data,
829                        unsigned int offset, unsigned int nevents) {
830         unsigned int j=0;
831         unsigned char *target = (unsigned char *)data + p->getPosition();
832
833         switch (p->getDataType()) {
834         default:
835         case Port::E_Int24:
836         case Port::E_Float:
837                 for (j = 0; j < nevents; j++) {
838                         *target = *(target+1) = *(target+2) = 0;
839                         target += m_event_size;
840                 }
841                 break;
842         }
843
844         return 0;
845 }
846
847 bool MotuTransmitStreamProcessor::preparedForStop() {
848
849         // If the stream is disabled or isn't running there's no need to
850         // wait since the MOTU *should* still be in a "zero data" state.
851         //
852         // If the m_streaming_active flag is 0 it indicates that the
853         // transmit callback hasn't been called since a closedown was
854         // requested when this function was last called.  This effectively
855         // signifies that the streaming thread has been exitted due to an
856         // xrun in either the receive or transmit handlers.  In this case
857         // there's no point in waiting for the closedown count to hit zero
858         // because it never will; the zero data will never get to the MOTU.
859         // It's best to allow an immediate stop and let the xrun handler
860         // proceed as best it can.
861         //
862         // The ability to detect the lack of streaming also prevents the
863         // "wait for stop" in the stream processor manager's stop() method
864         // from hitting its timeout which in turn seems to increase the
865         // probability of a successful recovery.
866         if (m_disabled || !isRunning() || !m_streaming_active)
867                 return true;
868
869         if (m_closedown_count < 0) {
870                 // No closedown has been initiated, so start one now.  Set
871                 // the closedown count to the number of zero packets which
872                 // will be sent to the MOTU before closing off the iso
873                 // streams.  FIXME: 128 packets (each containing 8 frames at
874                 // 48 kHz) is the experimentally-determined figure for 48
875                 // kHz with a period size of 1024.  It seems that at least
876                 // one period of zero samples need to be sent to allow for
877                 // inter-thread communication occuring on period boundaries.
878                 // This needs to be confirmed for other rates and period
879                 // sizes.
880                 signed n_events = m_framerate<=48000?8:(m_framerate<=96000?16:32);
881                 m_closedown_count = m_period / n_events;
882
883                 // Set up a test to confirm that streaming is still active.
884                 // If the streaming function hasn't been called by the next
885                 // iteration through this function there's no point in
886                 // continuing since it means the zero data will never get to
887                 // the MOTU.
888                 m_streaming_active = 0;
889                 return false;
890         }
891
892         // We are "go" for closedown once all requested zero packets
893         // (initiated by a previous call to this function) have been sent to
894         // the MOTU.
895         return m_closedown_count == 0;
896 }
897
898 bool MotuTransmitStreamProcessor::preparedForStart() {
899 // Reset some critical variables required so the stream starts cleanly. This
900 // method is called once on every stream restart, including those during
901 // xrun recovery.  Initialisations which should be done once should be
902 // placed in the init() method instead.
903         m_running = 0;
904         m_next_cycle = -1;
905         m_closedown_count = -1;
906         m_streaming_active = 0;
907         m_cycle_count = -1;
908         m_cycle_ofs = 0.0;
909
910         // At this point we'll also disable the stream processor here.
911         // At this stage stream processors are always explicitly re-enabled
912         // after being started, so by starting in the disabled state we
913         // ensure that every start will be exactly the same.
914         disable();
915
916         return true;
917 }
918
919 /* --------------------- RECEIVE ----------------------- */
920
921 MotuReceiveStreamProcessor::MotuReceiveStreamProcessor(int port, int framerate,
922         unsigned int event_size)
923     : ReceiveStreamProcessor(port, framerate), m_event_size(event_size),
924         m_last_cycle_ofs(-1), m_next_cycle(-1), m_closedown_active(0) {
925
926         // Set up the Delay-locked-loop to track audio frequency relative
927         // to the cycle timer.  The seed value is the "ideal" value.
928         m_ticks_per_frame = 24576000.0/framerate;
929 }
930
931 MotuReceiveStreamProcessor::~MotuReceiveStreamProcessor() {
932         freebob_ringbuffer_free(m_event_buffer);
933         free(m_tmp_event_buffer);
934 }
935
936 bool MotuReceiveStreamProcessor::init() {
937
938         // call the parent init
939         // this has to be done before allocating the buffers,
940         // because this sets the buffersizes from the processormanager
941         if(!ReceiveStreamProcessor::init()) {
942                 debugFatal("Could not do base class init (%d)\n",this);
943                 return false;
944         }
945
946         return true;
947 }
948
949 enum raw1394_iso_disposition
950 MotuReceiveStreamProcessor::putPacket(unsigned char *data, unsigned int length,
951                   unsigned char channel, unsigned char tag, unsigned char sy,
952                   unsigned int cycle, unsigned int dropped) {
953    
954         enum raw1394_iso_disposition retval=RAW1394_ISO_OK;
955         signed int have_lost_cycles = 0;
956
957         // Detect missed receive cycles
958         // FIXME: it would be nice to advance the rx buffer by the amount of
959         // frames missed.  However, since the MOTU transmits more frames per
960         // cycle than the average and "catches up" with periodic empty
961         // cycles it's not trivial to work out precisely how many frames
962         // were missed.  Ultimately I think we need to do so if sync is to
963         // be maintained across a transient receive failure.
964         if (m_next_cycle < 0)
965                 m_next_cycle = cycle;
966         if ((signed)cycle != m_next_cycle) {
967                 debugOutput(DEBUG_LEVEL_VERBOSE, "lost rx cycles; received %d, expected %d\n",
968                         cycle, m_next_cycle);
969                 m_next_cycle = cycle;
970                 have_lost_cycles = 1;
971         }
972         if (++m_next_cycle >= 8000)
973                 m_next_cycle -= 8000;
974
975         // If the packet length is 8 bytes (ie: just a CIP-like header)
976         // there is no isodata.
977         if (length > 8) {
978                 // The iso data blocks from the MOTUs comprise a CIP-like
979                 // header followed by a number of events (8 for 1x rates, 16
980                 // for 2x rates, 32 for 4x rates).
981                 quadlet_t *quadlet = (quadlet_t *)data;
982                 unsigned int dbs = get_bits(ntohl(quadlet[0]), 23, 8);  // Size of one event in terms of fdf_size
983                 unsigned int fdf_size = get_bits(ntohl(quadlet[1]), 23, 8) == 0x22 ? 32:0; // Event unit size in bits
984                 unsigned int event_length = (fdf_size * dbs) / 8;       // Event size in bytes
985                 unsigned int n_events = (length-8) / event_length;
986
987                 // Don't even attempt to process a packet if it isn't what
988                 // we expect from a MOTU.  Yes, an FDF value of 32 bears
989                 // little relationship to the actual data (24 bit integer)
990                 // sent by the MOTU - it's one of those areas where MOTU
991                 // have taken a curious detour around the standards.
992                 if (tag!=1 || fdf_size!=32) {
993                         return RAW1394_ISO_OK;
994                 }
995
996                 // Signal that we're running
997                 if (n_events) m_running=true;
998
999                 /* Send actual ticks-per-frame values (as deduced by the
1000                  * incoming SPHs) to the DLL for averaging.  Doing this here
1001                  * means the DLL should acquire a reasonable estimation of
1002                  * the ticks per frame even while the stream is formally
1003                  * disabled.  This in turn means the transmit stream should
1004                  * have access to a very realistic estimate by the time it
1005                  * is enabled.  The major disadvantage is a small increase
1006                  * in the overheads of this function compared to what would
1007                  * be the case if this was delayed by pushing it into the
1008                  * decode functions.
1009                  */
1010                 unsigned int ev;
1011                 signed int sph_ofs;
1012
1013                 /* If this is the first block received or we have lost
1014                  * cycles, initialise the m_last_cycle_ofs to a value which
1015                  * won't cause the DLL to become polluted with an
1016                  * inappropriate ticks-per-frame estimate.
1017                  */
1018                 if (m_last_cycle_ofs<0 || have_lost_cycles) {
1019                         sph_ofs = ntohl(*(quadlet_t *)(data+8)) & 0xfff;
1020                         m_last_cycle_ofs = sph_ofs-(int)(m_ticks_per_frame);
1021                 }
1022                 for (ev=0; ev<n_events; ev++) {
1023                         sph_ofs = ntohl(*(quadlet_t *)(data+8+ev*m_event_size)) & 0xfff;
1024                         signed int sph_diff = (sph_ofs - m_last_cycle_ofs);
1025                         // Handle wraparound of the cycle offset
1026                         if (sph_diff < 0)
1027                                 sph_diff += 3072;
1028                         float err = sph_diff - m_ticks_per_frame;
1029                         // FIXME: originally we used a value of 0.0005 for
1030                         // the coefficient which mirrored the value used in
1031                         // AmdtpReceiveStreamProcessor::putPacket() for a
1032                         // similar purpose.  However, tests showed that this
1033                         // introduced discontinuities in the output audio
1034                         // signal, so an alternative value was sought.
1035                         // Further tests are needed, but a value of 0.015
1036                         // seems to work well, at least at a sample rate of
1037                         // 48 kHz.
1038                         m_ticks_per_frame += 0.015*err;
1039                         m_last_cycle_ofs = sph_ofs;
1040                 }
1041
1042                 // Don't process the stream when it is not enabled
1043                 if (m_disabled) {
1044                         return RAW1394_ISO_OK;
1045                 }
1046
1047                 // If closedown is active we also just throw data way, but
1048                 // in this case we keep the frame counter going to prevent a
1049                 // false xrun detection
1050                 if (m_closedown_active) {
1051                         incrementFrameCounter(n_events);
1052                         if (m_framecounter > (signed int)m_period)
1053                                 return RAW1394_ISO_DEFER;
1054                         return RAW1394_ISO_OK;
1055                 }
1056
1057                 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "put packet...\n");
1058
1059                 // Add the data payload (events) to the ringbuffer.  We'll
1060                 // just copy everything including the 4 byte timestamp at
1061                 // the start of each event (that is, everything except the
1062                 // CIP-like header).  The demultiplexer can deal with the
1063                 // complexities such as the channel 24-bit data.
1064                 unsigned int write_size = length-8;
1065                 if (freebob_ringbuffer_write(m_event_buffer,(char *)(data+8),write_size) < write_size) {
1066                         debugWarning("Receive buffer overrun (cycle %d, FC=%d, PC=%d)\n",
1067                                 cycle, m_framecounter, m_handler->getPacketCount());
1068                         m_xruns++;
1069
1070                         retval=RAW1394_ISO_DEFER;
1071                 } else {
1072                         retval=RAW1394_ISO_OK;
1073                         // Process all ports that should be handled on a
1074                         // per-packet basis.  This is MIDI for AMDTP (due to
1075                         // the need of DBC)
1076                         int dbc = get_bits(ntohl(quadlet[0]), 8, 8);  // Low byte of CIP quadlet 0
1077                         if (!decodePacketPorts((quadlet_t *)(data+8), n_events, dbc)) {
1078                                 debugWarning("Problem decoding Packet Ports\n");
1079                                 retval=RAW1394_ISO_DEFER;
1080                         }
1081                         // time stamp processing can be done here
1082                 }
1083
1084                 // update the frame counter
1085                 incrementFrameCounter(n_events);
1086                 // keep this at the end, because otherwise the
1087                 // raw1394_loop_iterate functions inner loop keeps
1088                 // requesting packets without going to the xmit handler,
1089                 // leading to xmit starvation
1090                 if(m_framecounter>(signed int)m_period) {
1091                         retval=RAW1394_ISO_DEFER;
1092                 }
1093
1094         } else { // no events in packet
1095                 // discard packet
1096                 // can be important for sync though
1097         }
1098    
1099         return retval;
1100 }
1101
1102 bool MotuReceiveStreamProcessor::isOnePeriodReady() {
1103      // TODO: this is the way you can implement sync
1104      //       only when this returns true, one period will be
1105      //       transferred to the audio api side.
1106      //       you can delay this moment as long as you
1107      //       want (provided that there is enough buffer space)
1108      
1109      // this implementation just waits until there is one period of samples
1110      // received into the buffer
1111     if(m_framecounter > (signed int)m_period) {
1112         return true;
1113     }
1114     return false;
1115 }
1116
1117 void MotuReceiveStreamProcessor::setVerboseLevel(int l) {
1118         setDebugLevel(l);
1119         ReceiveStreamProcessor::setVerboseLevel(l);
1120
1121 }
1122
1123
1124 bool MotuReceiveStreamProcessor::reset() {
1125
1126         debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n");
1127
1128         // reset the event buffer, discard all content
1129         freebob_ringbuffer_reset(m_event_buffer);
1130
1131         // reset all non-device specific stuff
1132         // i.e. the iso stream and the associated ports
1133         if(!ReceiveStreamProcessor::reset()) {
1134                 debugFatal("Could not do base class reset\n");
1135                 return false;
1136         }
1137
1138         m_next_cycle = -1;
1139
1140         return true;
1141 }
1142
1143 bool MotuReceiveStreamProcessor::prepare() {
1144
1145         // prepare all non-device specific stuff
1146         // i.e. the iso stream and the associated ports
1147         if(!ReceiveStreamProcessor::prepare()) {
1148                 debugFatal("Could not prepare base class\n");
1149                 return false;
1150         }
1151
1152         debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing...\n");
1153
1154         m_PeriodStat.setName("RCV PERIOD");
1155         m_PacketStat.setName("RCV PACKET");
1156         m_WakeupStat.setName("RCV WAKEUP");
1157
1158     // setup any specific stuff here
1159
1160         debugOutput( DEBUG_LEVEL_VERBOSE, "Event size: %d\n", m_event_size);
1161    
1162         // allocate the event buffer
1163         unsigned int ringbuffer_size_frames=m_nb_buffers * m_period;
1164
1165         if( !(m_event_buffer=freebob_ringbuffer_create(
1166                         m_event_size * ringbuffer_size_frames))) {
1167                 debugFatal("Could not allocate memory event ringbuffer");
1168                 return false;
1169         }
1170
1171         // allocate the temporary event buffer
1172         if( !(m_tmp_event_buffer=(char *)calloc(1,m_event_size))) {
1173                 debugFatal("Could not allocate temporary event buffer");
1174                 freebob_ringbuffer_free(m_event_buffer);
1175                 return false;
1176         }
1177
1178         // set the parameters of ports we can:
1179         // we want the audio ports to be period buffered,
1180         // and the midi ports to be packet buffered
1181         for ( PortVectorIterator it = m_Ports.begin();
1182                   it != m_Ports.end();
1183                   ++it )
1184         {
1185                 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
1186                
1187                 if(!(*it)->setBufferSize(m_period)) {
1188                         debugFatal("Could not set buffer size to %d\n",m_period);
1189                         return false;
1190                 }
1191
1192                 switch ((*it)->getPortType()) {
1193                         case Port::E_Audio:
1194                                 if(!(*it)->setSignalType(Port::E_PeriodSignalled)) {
1195                                         debugFatal("Could not set signal type to PeriodSignalling");
1196                                         return false;
1197                                 }
1198                                 break;
1199                         case Port::E_Midi:
1200                                 if(!(*it)->setSignalType(Port::E_PacketSignalled)) {
1201                                         debugFatal("Could not set signal type to PacketSignalling");
1202                                         return false;
1203                                 }
1204                                 if (!(*it)->setBufferType(Port::E_RingBuffer)) {
1205                                         debugFatal("Could not set buffer type");
1206                                         return false;
1207                                 }
1208                                 if (!(*it)->setDataType(Port::E_MidiEvent)) {
1209                                         debugFatal("Could not set data type");
1210                                         return false;
1211                                 }
1212                                 // FIXME: probably need rate control too.  See
1213                                 // Port::useRateControl() and AmdtpStreamProcessor.
1214                                 break;
1215                         case Port::E_Control:
1216                                 if(!(*it)->setSignalType(Port::E_PeriodSignalled)) {
1217                                         debugFatal("Could not set signal type to PeriodSignalling");
1218                                         return false;
1219                                 }
1220                                 break;
1221                         default:
1222                                 debugWarning("Unsupported port type specified\n");
1223                                 break;
1224                 }
1225
1226         }
1227
1228         // The API specific settings of the ports are already set before
1229         // this routine is called, therefore we can init&prepare the ports
1230         if(!initPorts()) {
1231                 debugFatal("Could not initialize ports!\n");
1232                 return false;
1233         }
1234
1235         if(!preparePorts()) {
1236                 debugFatal("Could not initialize ports!\n");
1237                 return false;
1238         }
1239        
1240         return true;
1241
1242 }
1243
1244 bool MotuReceiveStreamProcessor::transfer() {
1245
1246     // the same idea as the transmit processor
1247    
1248         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n");
1249        
1250 /* another naive section:       
1251         unsigned int read_size=m_period*m_event_size;
1252         char *dummybuffer=(char *)calloc(m_period,m_event_size);
1253         if (freebob_ringbuffer_read(m_event_buffer,(char *)(dummybuffer),read_size) < read_size) {
1254                 debugWarning("Could not read from event buffer\n");
1255         }
1256
1257         receiveBlock(dummybuffer, m_period, 0);
1258
1259         free(dummybuffer);
1260 */
1261         int xrun;
1262         unsigned int offset=0;
1263        
1264         freebob_ringbuffer_data_t vec[2];
1265         // We received one period of frames from each channel.
1266         // This is period_size*m_event_size bytes.
1267         unsigned int bytes2read = m_period * m_event_size;
1268
1269         // If closedown is in progress just pretend that data's been transferred
1270         // to prevent false underrun detections on the event buffer.
1271         if (m_closedown_active)
1272                 return true;
1273
1274         /* Read events2read bytes from the ringbuffer.
1275         *  First see if it can be done in one read.  If so, ok.
1276         *  Otherwise read up to a multiple of events directly from the buffer
1277         *  then do the buffer wrap around using ringbuffer_read
1278         *  then read the remaining data directly from the buffer in a third pass
1279         *  Make sure that we cannot end up on a non-event aligned position!
1280         */
1281         while(bytes2read>0) {
1282                 unsigned int framesread=(m_period*m_event_size-bytes2read)/m_event_size;
1283                 offset=framesread;
1284                
1285                 int bytesread=0;
1286
1287                 freebob_ringbuffer_get_read_vector(m_event_buffer, vec);
1288                        
1289                 if(vec[0].len==0) { // this indicates an empty event buffer
1290                         debugError("RCV: Event buffer underrun in processor %p\n",this);
1291                         break;
1292                 }
1293                        
1294                 /* if we don't take care we will get stuck in an infinite loop
1295                 * because we align to an event boundary later
1296                 * the remaining nb of bytes in one read operation can be smaller than one event
1297                 * this can happen because the ringbuffer size is always a power of 2
1298                 */
1299                 if(vec[0].len<m_event_size) {
1300                         // use the ringbuffer function to read one event
1301                         // the read function handles wrap around
1302                         freebob_ringbuffer_read(m_event_buffer,m_tmp_event_buffer,m_event_size);
1303
1304                         xrun = receiveBlock(m_tmp_event_buffer, 1, offset);
1305                                
1306                         if(xrun<0) {
1307                                 // xrun detected
1308                                 debugError("RCV: Frame buffer overrun in processor %p\n",this);
1309                                 break;
1310                         }
1311                                
1312                         // We advanced one m_event_size
1313                         bytes2read-=m_event_size;
1314                                
1315                 } else { //
1316                        
1317                         if(bytes2read>vec[0].len) {
1318                                         // align to an event boundary
1319                                 bytesread=vec[0].len-(vec[0].len%m_event_size);
1320                         } else {
1321                                 bytesread=bytes2read;
1322                         }
1323                                
1324                         xrun = receiveBlock(vec[0].buf, bytesread/m_event_size, offset);
1325                                
1326                         if(xrun<0) {
1327                                 // xrun detected
1328                                 debugError("RCV: Frame buffer overrun in processor %p\n",this);
1329                                 break;
1330                         }
1331
1332                         freebob_ringbuffer_read_advance(m_event_buffer, bytesread);
1333                         bytes2read -= bytesread;
1334                 }
1335                        
1336                 // the bytes2read should always be event aligned
1337                 assert(bytes2read%m_event_size==0);
1338         }
1339
1340         return true;
1341 }
1342
1343 /**
1344  * \brief write received events to the port ringbuffers.
1345  */
1346 int MotuReceiveStreamProcessor::receiveBlock(char *data,
1347                                            unsigned int nevents, unsigned int offset)
1348 {
1349         int problem=0;
1350         for ( PortVectorIterator it = m_PeriodPorts.begin();
1351           it != m_PeriodPorts.end();
1352           ++it ) {
1353                 if((*it)->isDisabled()) {continue;};
1354
1355                 //FIXME: make this into a static_cast when not DEBUG?
1356                 Port *port=dynamic_cast<Port *>(*it);
1357                
1358                 switch(port->getPortType()) {
1359                
1360                 case Port::E_Audio:
1361                         if(decodeMBLAEventsToPort(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
1362                                 debugWarning("Could not decode packet MBLA to port %s",(*it)->getName().c_str());
1363                                 problem=1;
1364                         }
1365                         break;
1366                 // midi is a packet based port, don't process
1367                 //      case MotuPortInfo::E_Midi:
1368                 //              break;
1369
1370                 default: // ignore
1371                         break;
1372                 }
1373         }
1374         return problem;
1375 }
1376
1377 /**
1378  * @brief decode a packet for the packet-based ports
1379  *
1380  * @param data Packet data
1381  * @param nevents number of events in data (including events of other ports & port types)
1382  * @param dbc DataBlockCount value for this packet
1383  * @return true if all successfull
1384  */
1385 bool MotuReceiveStreamProcessor::decodePacketPorts(quadlet_t *data, unsigned int nevents,
1386                 unsigned int dbc) {
1387         bool ok=true;
1388
1389         // Use char here since the source address won't necessarily be
1390         // aligned; use of an unaligned quadlet_t may cause issues on
1391         // certain architectures.  Besides, the source for MIDI data going
1392         // directly to the MOTU isn't structured in quadlets anyway; it is a
1393         // sequence of 3 unaligned bytes.
1394         unsigned char *src = NULL;
1395
1396         for ( PortVectorIterator it = m_PacketPorts.begin();
1397                 it != m_PacketPorts.end();
1398                 ++it ) {
1399
1400 #ifdef DEBUG
1401                 //FIXME: make these into a static_casts when not DEBUG?
1402                 Port *port=dynamic_cast<Port *>(*it);
1403                 assert(port); // this should not fail!!
1404
1405                 // Currently the only packet type of events for MOTU
1406                 // is MIDI in mbla.  However in future control data
1407                 // might also be sent via "packet" events, so allow
1408                 // for this possible expansion.
1409 #endif
1410                 // FIXME: MIDI input is completely untested at present.
1411                 switch (port->getPortType()) {
1412                         case Port::E_Midi: {
1413                                 MotuMidiPort *mp=static_cast<MotuMidiPort *>(*it);
1414                                 signed int sample;
1415                                 unsigned int j = 0;
1416                                 // Get MIDI bytes if present anywhere in the
1417                                 // packet.  MOTU MIDI data is sent using a
1418                                 // 3-byte sequence starting at the port's
1419                                 // position.  It's thought that there can never
1420                                 // be more than one MIDI byte per packet, but
1421                                 // for completeness we'll check the entire packet
1422                                 // anyway.
1423                                 src = (unsigned char *)data + mp->getPosition();
1424                                 while (j < nevents) {
1425                                         if (*src==0x01 && *(src+1)==0x00) {
1426                                                 sample = *(src+2);
1427                                                 if (!mp->writeEvent(&sample)) {
1428                                                         debugWarning("MIDI packet port events lost\n");
1429                                                         ok = false;
1430                                                 }
1431                                         }
1432                                         j++;
1433                                         src += m_event_size;
1434                                 }
1435                                 break;
1436                         }
1437                         default:
1438                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown packet-type port format %d\n",port->getPortType());
1439                                 return ok;       
1440                 }
1441         }
1442
1443         return ok;
1444 }
1445
1446 signed int MotuReceiveStreamProcessor::decodeMBLAEventsToPort(MotuAudioPort *p,
1447                 quadlet_t *data, unsigned int offset, unsigned int nevents)
1448 {
1449         unsigned int j=0;
1450
1451         // Use char here since a port's source address won't necessarily be
1452         // aligned; use of an unaligned quadlet_t may cause issues on
1453         // certain architectures.  Besides, the source (data coming directly
1454         // from the MOTU) isn't structured in quadlets anyway; it mainly
1455         // consists of packed 24-bit integers.
1456
1457         unsigned char *src_data;
1458         src_data = (unsigned char *)data + p->getPosition();
1459
1460         switch(p->getDataType()) {
1461                 default:
1462                 case Port::E_Int24:
1463                         {
1464                                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
1465
1466                                 assert(nevents + offset <= p->getBufferSize());
1467
1468                                 // Offset is in frames, but each port is only a single
1469                                 // channel, so the number of frames is the same as the
1470                                 // number of quadlets to offset (assuming the port buffer
1471                                 // uses one quadlet per sample, which is the case currently).
1472                                 buffer+=offset;
1473
1474                                 for(j = 0; j < nevents; j += 1) { // Decode nsamples
1475                                         *buffer = (*src_data<<16)+(*(src_data+1)<<8)+*(src_data+2);
1476                                         // Sign-extend highest bit of 24-bit int.
1477                                         // FIXME: this isn't strictly needed since E_Int24 is a 24-bit,
1478                                         // but doing so shouldn't break anything and makes the data
1479                                         // easier to deal with during debugging.
1480                                         if (*src_data & 0x80)
1481                                                 *buffer |= 0xff000000;
1482
1483                                         buffer++;
1484                                         src_data+=m_event_size;
1485                                 }
1486                         }
1487                         break;
1488                 case Port::E_Float:
1489                         {
1490                                 const float multiplier = 1.0f / (float)(0x7FFFFF);
1491                                 float *buffer=(float *)(p->getBufferAddress());
1492
1493                                 assert(nevents + offset <= p->getBufferSize());
1494
1495                                 buffer+=offset;
1496
1497                                 for(j = 0; j < nevents; j += 1) { // decode max nsamples               
1498        
1499                                         unsigned int v = (*src_data<<16)+(*(src_data+1)<<8)+*(src_data+2);
1500
1501                                         // sign-extend highest bit of 24-bit int
1502                                         int tmp = (int)(v << 8) / 256;
1503                
1504                                         *buffer = tmp * multiplier;
1505                                
1506                                         buffer++;
1507                                         src_data+=m_event_size;
1508                                 }
1509                         }
1510                         break;
1511         }
1512
1513         return 0;
1514 }
1515
1516 signed int MotuReceiveStreamProcessor::setEventSize(unsigned int size) {
1517         m_event_size = size;
1518         return 0;
1519 }
1520
1521 unsigned int MotuReceiveStreamProcessor::getEventSize(void) {
1522 //
1523 // Return the size of a single event sent by the MOTU as part of an iso
1524 // data packet in bytes.
1525 //
1526         return m_event_size;
1527 }
1528
1529 bool MotuReceiveStreamProcessor::preparedForStop() {
1530
1531         // A MOTU receive stream can stop at any time.  However, signify
1532         // that stopping is in progress because other streams (notably the
1533         // transmit stream) may keep going for some time and cause an
1534         // overflow in the receive buffers.  If a closedown is in progress
1535         // the receive handler simply throws all incoming data away so
1536         // no buffer overflow can occur.
1537         m_closedown_active = 1;
1538         return true;
1539 }
1540
1541 bool MotuReceiveStreamProcessor::preparedForStart() {
1542 // Reset some critical variables required so the stream starts cleanly. This
1543 // method is called once on every stream restart, including those during
1544 // xrun recovery.  Initialisations which should be done once should be
1545 // placed in the init() method instead.
1546         m_running = 0;
1547         m_next_cycle = -1;
1548         m_closedown_active = 0;
1549         m_last_cycle_ofs = -1;
1550
1551         // At this point we'll also disable the stream processor here.
1552         // At this stage stream processors are always explicitly re-enabled
1553         // after being started, so by starting in the disabled state we
1554         // ensure that every start will be exactly the same.
1555         disable();
1556
1557         return true;
1558 }
1559
1560                
1561 } // end of namespace FreebobStreaming
Note: See TracBrowser for help on using the browser.