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

Revision 333, 48.6 kB (checked in by pieterpalmers, 16 years ago)

- bump version to 1.999.0 such that it stays ahead of 1.x
- fix issue that prevented the code from

being compiled for --disable-debug

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                 Port *port=static_cast<Port *>(*it);
715                 assert(port); // this should not fail!!
716
717                 // Currently the only packet type of events for MOTU
718                 // is MIDI in mbla.  However in future control data
719                 // might also be sent via "packet" events.
720                 // assert(pinfo->getFormat()==MotuPortInfo::E_Midi);
721
722                 // FIXME: MIDI output is completely untested at present.
723                 switch (port->getPortType()) {
724                         case Port::E_Midi: {
725                                 MotuMidiPort *mp=static_cast<MotuMidiPort *>(*it);
726
727                                 // Send a byte if we can. MOTU MIDI data is
728                                 // sent using a 3-byte sequence starting at
729                                 // the port's position.  For now we'll
730                                 // always send in the first event of a
731                                 // packet, but this might need refinement
732                                 // later.
733                                 if (mp->canRead()) {
734                                         mp->readEvent(&byte);
735                                         target = (unsigned char *)data + mp->getPosition();
736                                         *(target++) = 0x01;
737                                         *(target++) = 0x00;
738                                         *(target++) = byte;
739                                 }
740                                 break;
741                         }
742                         default:
743                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown packet-type port type %d\n",port->getPortType());
744                                 return ok;       
745                 }
746         }
747
748         return ok;
749 }
750
751 int MotuTransmitStreamProcessor::encodePortToMBLAEvents(MotuAudioPort *p, quadlet_t *data,
752                        unsigned int offset, unsigned int nevents) {
753 // Encodes nevents worth of data from the given port into the given buffer.  The
754 // format of the buffer is precisely that which will be sent to the MOTU.
755 // The basic idea:
756 //   iterate over the ports
757 //     * get port buffer address
758 //     * loop over events
759 //         - pick right sample in event based upon PortInfo
760 //         - convert sample from Port format (E_Int24, E_Float, ..) to MOTU
761 //           native format
762 //
763 // We include the ability to start the transfer from the given offset within
764 // the port (expressed in frames) so the 'efficient' transfer method can be
765 // utilised.
766
767         unsigned int j=0;
768
769         // Use char here since the target address won't necessarily be
770         // aligned; use of an unaligned quadlet_t may cause issues on certain
771         // architectures.  Besides, the target (data going directly to the MOTU)
772         // isn't structured in quadlets anyway; it mainly consists of packed
773         // 24-bit integers.
774         unsigned char *target;
775         target = (unsigned char *)data + p->getPosition();
776
777         switch(p->getDataType()) {
778                 default:
779                 case Port::E_Int24:
780                         {
781                                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
782
783                                 assert(nevents + offset <= p->getBufferSize());
784
785                                 // Offset is in frames, but each port is only a single
786                                 // channel, so the number of frames is the same as the
787                                 // number of quadlets to offset (assuming the port buffer
788                                 // uses one quadlet per sample, which is the case currently).
789                                 buffer+=offset;
790
791                                 for(j = 0; j < nevents; j += 1) { // Decode nsamples
792                                         *target = (*buffer >> 16) & 0xff;
793                                         *(target+1) = (*buffer >> 8) & 0xff;
794                                         *(target+2) = (*buffer) & 0xff;
795
796                                         buffer++;
797                                         target+=m_event_size;
798                                 }
799                         }
800                         break;
801                 case Port::E_Float:
802                         {
803                                 const float multiplier = (float)(0x7FFFFF);
804                                 float *buffer=(float *)(p->getBufferAddress());
805
806                                 assert(nevents + offset <= p->getBufferSize());
807
808                                 buffer+=offset;
809
810                                 for(j = 0; j < nevents; j += 1) { // decode max nsamples               
811                                         unsigned int v = (int)(*buffer * multiplier);
812                                         *target = (v >> 16) & 0xff;
813                                         *(target+1) = (v >> 8) & 0xff;
814                                         *(target+2) = v & 0xff;
815
816                                         buffer++;
817                                         target+=m_event_size;
818                                 }
819                         }
820                         break;
821         }
822
823         return 0;
824 }
825
826 int MotuTransmitStreamProcessor::encodeSilencePortToMBLAEvents(MotuAudioPort *p, quadlet_t *data,
827                        unsigned int offset, unsigned int nevents) {
828         unsigned int j=0;
829         unsigned char *target = (unsigned char *)data + p->getPosition();
830
831         switch (p->getDataType()) {
832         default:
833         case Port::E_Int24:
834         case Port::E_Float:
835                 for (j = 0; j < nevents; j++) {
836                         *target = *(target+1) = *(target+2) = 0;
837                         target += m_event_size;
838                 }
839                 break;
840         }
841
842         return 0;
843 }
844
845 bool MotuTransmitStreamProcessor::preparedForStop() {
846
847         // If the stream is disabled or isn't running there's no need to
848         // wait since the MOTU *should* still be in a "zero data" state.
849         //
850         // If the m_streaming_active flag is 0 it indicates that the
851         // transmit callback hasn't been called since a closedown was
852         // requested when this function was last called.  This effectively
853         // signifies that the streaming thread has been exitted due to an
854         // xrun in either the receive or transmit handlers.  In this case
855         // there's no point in waiting for the closedown count to hit zero
856         // because it never will; the zero data will never get to the MOTU.
857         // It's best to allow an immediate stop and let the xrun handler
858         // proceed as best it can.
859         //
860         // The ability to detect the lack of streaming also prevents the
861         // "wait for stop" in the stream processor manager's stop() method
862         // from hitting its timeout which in turn seems to increase the
863         // probability of a successful recovery.
864         if (m_disabled || !isRunning() || !m_streaming_active)
865                 return true;
866
867         if (m_closedown_count < 0) {
868                 // No closedown has been initiated, so start one now.  Set
869                 // the closedown count to the number of zero packets which
870                 // will be sent to the MOTU before closing off the iso
871                 // streams.  FIXME: 128 packets (each containing 8 frames at
872                 // 48 kHz) is the experimentally-determined figure for 48
873                 // kHz with a period size of 1024.  It seems that at least
874                 // one period of zero samples need to be sent to allow for
875                 // inter-thread communication occuring on period boundaries.
876                 // This needs to be confirmed for other rates and period
877                 // sizes.
878                 signed n_events = m_framerate<=48000?8:(m_framerate<=96000?16:32);
879                 m_closedown_count = m_period / n_events;
880
881                 // Set up a test to confirm that streaming is still active.
882                 // If the streaming function hasn't been called by the next
883                 // iteration through this function there's no point in
884                 // continuing since it means the zero data will never get to
885                 // the MOTU.
886                 m_streaming_active = 0;
887                 return false;
888         }
889
890         // We are "go" for closedown once all requested zero packets
891         // (initiated by a previous call to this function) have been sent to
892         // the MOTU.
893         return m_closedown_count == 0;
894 }
895
896 bool MotuTransmitStreamProcessor::preparedForStart() {
897 // Reset some critical variables required so the stream starts cleanly. This
898 // method is called once on every stream restart, including those during
899 // xrun recovery.  Initialisations which should be done once should be
900 // placed in the init() method instead.
901         m_running = 0;
902         m_next_cycle = -1;
903         m_closedown_count = -1;
904         m_streaming_active = 0;
905         m_cycle_count = -1;
906         m_cycle_ofs = 0.0;
907
908         // At this point we'll also disable the stream processor here.
909         // At this stage stream processors are always explicitly re-enabled
910         // after being started, so by starting in the disabled state we
911         // ensure that every start will be exactly the same.
912         disable();
913
914         return true;
915 }
916
917 /* --------------------- RECEIVE ----------------------- */
918
919 MotuReceiveStreamProcessor::MotuReceiveStreamProcessor(int port, int framerate,
920         unsigned int event_size)
921     : ReceiveStreamProcessor(port, framerate), m_event_size(event_size),
922         m_last_cycle_ofs(-1), m_next_cycle(-1), m_closedown_active(0) {
923
924         // Set up the Delay-locked-loop to track audio frequency relative
925         // to the cycle timer.  The seed value is the "ideal" value.
926         m_ticks_per_frame = 24576000.0/framerate;
927 }
928
929 MotuReceiveStreamProcessor::~MotuReceiveStreamProcessor() {
930         freebob_ringbuffer_free(m_event_buffer);
931         free(m_tmp_event_buffer);
932 }
933
934 bool MotuReceiveStreamProcessor::init() {
935
936         // call the parent init
937         // this has to be done before allocating the buffers,
938         // because this sets the buffersizes from the processormanager
939         if(!ReceiveStreamProcessor::init()) {
940                 debugFatal("Could not do base class init (%d)\n",this);
941                 return false;
942         }
943
944         return true;
945 }
946
947 enum raw1394_iso_disposition
948 MotuReceiveStreamProcessor::putPacket(unsigned char *data, unsigned int length,
949                   unsigned char channel, unsigned char tag, unsigned char sy,
950                   unsigned int cycle, unsigned int dropped) {
951    
952         enum raw1394_iso_disposition retval=RAW1394_ISO_OK;
953         signed int have_lost_cycles = 0;
954
955         // Detect missed receive cycles
956         // FIXME: it would be nice to advance the rx buffer by the amount of
957         // frames missed.  However, since the MOTU transmits more frames per
958         // cycle than the average and "catches up" with periodic empty
959         // cycles it's not trivial to work out precisely how many frames
960         // were missed.  Ultimately I think we need to do so if sync is to
961         // be maintained across a transient receive failure.
962         if (m_next_cycle < 0)
963                 m_next_cycle = cycle;
964         if ((signed)cycle != m_next_cycle) {
965                 debugOutput(DEBUG_LEVEL_VERBOSE, "lost rx cycles; received %d, expected %d\n",
966                         cycle, m_next_cycle);
967                 m_next_cycle = cycle;
968                 have_lost_cycles = 1;
969         }
970         if (++m_next_cycle >= 8000)
971                 m_next_cycle -= 8000;
972
973         // If the packet length is 8 bytes (ie: just a CIP-like header)
974         // there is no isodata.
975         if (length > 8) {
976                 // The iso data blocks from the MOTUs comprise a CIP-like
977                 // header followed by a number of events (8 for 1x rates, 16
978                 // for 2x rates, 32 for 4x rates).
979                 quadlet_t *quadlet = (quadlet_t *)data;
980                 unsigned int dbs = get_bits(ntohl(quadlet[0]), 23, 8);  // Size of one event in terms of fdf_size
981                 unsigned int fdf_size = get_bits(ntohl(quadlet[1]), 23, 8) == 0x22 ? 32:0; // Event unit size in bits
982                 unsigned int event_length = (fdf_size * dbs) / 8;       // Event size in bytes
983                 unsigned int n_events = (length-8) / event_length;
984
985                 // Don't even attempt to process a packet if it isn't what
986                 // we expect from a MOTU.  Yes, an FDF value of 32 bears
987                 // little relationship to the actual data (24 bit integer)
988                 // sent by the MOTU - it's one of those areas where MOTU
989                 // have taken a curious detour around the standards.
990                 if (tag!=1 || fdf_size!=32) {
991                         return RAW1394_ISO_OK;
992                 }
993
994                 // Signal that we're running
995                 if (n_events) m_running=true;
996
997                 /* Send actual ticks-per-frame values (as deduced by the
998                  * incoming SPHs) to the DLL for averaging.  Doing this here
999                  * means the DLL should acquire a reasonable estimation of
1000                  * the ticks per frame even while the stream is formally
1001                  * disabled.  This in turn means the transmit stream should
1002                  * have access to a very realistic estimate by the time it
1003                  * is enabled.  The major disadvantage is a small increase
1004                  * in the overheads of this function compared to what would
1005                  * be the case if this was delayed by pushing it into the
1006                  * decode functions.
1007                  */
1008                 unsigned int ev;
1009                 signed int sph_ofs;
1010
1011                 /* If this is the first block received or we have lost
1012                  * cycles, initialise the m_last_cycle_ofs to a value which
1013                  * won't cause the DLL to become polluted with an
1014                  * inappropriate ticks-per-frame estimate.
1015                  */
1016                 if (m_last_cycle_ofs<0 || have_lost_cycles) {
1017                         sph_ofs = ntohl(*(quadlet_t *)(data+8)) & 0xfff;
1018                         m_last_cycle_ofs = sph_ofs-(int)(m_ticks_per_frame);
1019                 }
1020                 for (ev=0; ev<n_events; ev++) {
1021                         sph_ofs = ntohl(*(quadlet_t *)(data+8+ev*m_event_size)) & 0xfff;
1022                         signed int sph_diff = (sph_ofs - m_last_cycle_ofs);
1023                         // Handle wraparound of the cycle offset
1024                         if (sph_diff < 0)
1025                                 sph_diff += 3072;
1026                         float err = sph_diff - m_ticks_per_frame;
1027                         // FIXME: originally we used a value of 0.0005 for
1028                         // the coefficient which mirrored the value used in
1029                         // AmdtpReceiveStreamProcessor::putPacket() for a
1030                         // similar purpose.  However, tests showed that this
1031                         // introduced discontinuities in the output audio
1032                         // signal, so an alternative value was sought.
1033                         // Further tests are needed, but a value of 0.015
1034                         // seems to work well, at least at a sample rate of
1035                         // 48 kHz.
1036                         m_ticks_per_frame += 0.015*err;
1037                         m_last_cycle_ofs = sph_ofs;
1038                 }
1039
1040                 // Don't process the stream when it is not enabled
1041                 if (m_disabled) {
1042                         return RAW1394_ISO_OK;
1043                 }
1044
1045                 // If closedown is active we also just throw data way, but
1046                 // in this case we keep the frame counter going to prevent a
1047                 // false xrun detection
1048                 if (m_closedown_active) {
1049                         incrementFrameCounter(n_events);
1050                         if (m_framecounter > (signed int)m_period)
1051                                 return RAW1394_ISO_DEFER;
1052                         return RAW1394_ISO_OK;
1053                 }
1054
1055                 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "put packet...\n");
1056
1057                 // Add the data payload (events) to the ringbuffer.  We'll
1058                 // just copy everything including the 4 byte timestamp at
1059                 // the start of each event (that is, everything except the
1060                 // CIP-like header).  The demultiplexer can deal with the
1061                 // complexities such as the channel 24-bit data.
1062                 unsigned int write_size = length-8;
1063                 if (freebob_ringbuffer_write(m_event_buffer,(char *)(data+8),write_size) < write_size) {
1064                         debugWarning("Receive buffer overrun (cycle %d, FC=%d, PC=%d)\n",
1065                                 cycle, m_framecounter, m_handler->getPacketCount());
1066                         m_xruns++;
1067
1068                         retval=RAW1394_ISO_DEFER;
1069                 } else {
1070                         retval=RAW1394_ISO_OK;
1071                         // Process all ports that should be handled on a
1072                         // per-packet basis.  This is MIDI for AMDTP (due to
1073                         // the need of DBC)
1074                         int dbc = get_bits(ntohl(quadlet[0]), 8, 8);  // Low byte of CIP quadlet 0
1075                         if (!decodePacketPorts((quadlet_t *)(data+8), n_events, dbc)) {
1076                                 debugWarning("Problem decoding Packet Ports\n");
1077                                 retval=RAW1394_ISO_DEFER;
1078                         }
1079                         // time stamp processing can be done here
1080                 }
1081
1082                 // update the frame counter
1083                 incrementFrameCounter(n_events);
1084                 // keep this at the end, because otherwise the
1085                 // raw1394_loop_iterate functions inner loop keeps
1086                 // requesting packets without going to the xmit handler,
1087                 // leading to xmit starvation
1088                 if(m_framecounter>(signed int)m_period) {
1089                         retval=RAW1394_ISO_DEFER;
1090                 }
1091
1092         } else { // no events in packet
1093                 // discard packet
1094                 // can be important for sync though
1095         }
1096    
1097         return retval;
1098 }
1099
1100 bool MotuReceiveStreamProcessor::isOnePeriodReady() {
1101      // TODO: this is the way you can implement sync
1102      //       only when this returns true, one period will be
1103      //       transferred to the audio api side.
1104      //       you can delay this moment as long as you
1105      //       want (provided that there is enough buffer space)
1106      
1107      // this implementation just waits until there is one period of samples
1108      // received into the buffer
1109     if(m_framecounter > (signed int)m_period) {
1110         return true;
1111     }
1112     return false;
1113 }
1114
1115 void MotuReceiveStreamProcessor::setVerboseLevel(int l) {
1116         setDebugLevel(l);
1117         ReceiveStreamProcessor::setVerboseLevel(l);
1118
1119 }
1120
1121
1122 bool MotuReceiveStreamProcessor::reset() {
1123
1124         debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting...\n");
1125
1126         // reset the event buffer, discard all content
1127         freebob_ringbuffer_reset(m_event_buffer);
1128
1129         // reset all non-device specific stuff
1130         // i.e. the iso stream and the associated ports
1131         if(!ReceiveStreamProcessor::reset()) {
1132                 debugFatal("Could not do base class reset\n");
1133                 return false;
1134         }
1135
1136         m_next_cycle = -1;
1137
1138         return true;
1139 }
1140
1141 bool MotuReceiveStreamProcessor::prepare() {
1142
1143         // prepare all non-device specific stuff
1144         // i.e. the iso stream and the associated ports
1145         if(!ReceiveStreamProcessor::prepare()) {
1146                 debugFatal("Could not prepare base class\n");
1147                 return false;
1148         }
1149
1150         debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing...\n");
1151
1152         m_PeriodStat.setName("RCV PERIOD");
1153         m_PacketStat.setName("RCV PACKET");
1154         m_WakeupStat.setName("RCV WAKEUP");
1155
1156     // setup any specific stuff here
1157
1158         debugOutput( DEBUG_LEVEL_VERBOSE, "Event size: %d\n", m_event_size);
1159    
1160         // allocate the event buffer
1161         unsigned int ringbuffer_size_frames=m_nb_buffers * m_period;
1162
1163         if( !(m_event_buffer=freebob_ringbuffer_create(
1164                         m_event_size * ringbuffer_size_frames))) {
1165                 debugFatal("Could not allocate memory event ringbuffer");
1166                 return false;
1167         }
1168
1169         // allocate the temporary event buffer
1170         if( !(m_tmp_event_buffer=(char *)calloc(1,m_event_size))) {
1171                 debugFatal("Could not allocate temporary event buffer");
1172                 freebob_ringbuffer_free(m_event_buffer);
1173                 return false;
1174         }
1175
1176         // set the parameters of ports we can:
1177         // we want the audio ports to be period buffered,
1178         // and the midi ports to be packet buffered
1179         for ( PortVectorIterator it = m_Ports.begin();
1180                   it != m_Ports.end();
1181                   ++it )
1182         {
1183                 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting up port %s\n",(*it)->getName().c_str());
1184                
1185                 if(!(*it)->setBufferSize(m_period)) {
1186                         debugFatal("Could not set buffer size to %d\n",m_period);
1187                         return false;
1188                 }
1189
1190                 switch ((*it)->getPortType()) {
1191                         case Port::E_Audio:
1192                                 if(!(*it)->setSignalType(Port::E_PeriodSignalled)) {
1193                                         debugFatal("Could not set signal type to PeriodSignalling");
1194                                         return false;
1195                                 }
1196                                 break;
1197                         case Port::E_Midi:
1198                                 if(!(*it)->setSignalType(Port::E_PacketSignalled)) {
1199                                         debugFatal("Could not set signal type to PacketSignalling");
1200                                         return false;
1201                                 }
1202                                 if (!(*it)->setBufferType(Port::E_RingBuffer)) {
1203                                         debugFatal("Could not set buffer type");
1204                                         return false;
1205                                 }
1206                                 if (!(*it)->setDataType(Port::E_MidiEvent)) {
1207                                         debugFatal("Could not set data type");
1208                                         return false;
1209                                 }
1210                                 // FIXME: probably need rate control too.  See
1211                                 // Port::useRateControl() and AmdtpStreamProcessor.
1212                                 break;
1213                         case Port::E_Control:
1214                                 if(!(*it)->setSignalType(Port::E_PeriodSignalled)) {
1215                                         debugFatal("Could not set signal type to PeriodSignalling");
1216                                         return false;
1217                                 }
1218                                 break;
1219                         default:
1220                                 debugWarning("Unsupported port type specified\n");
1221                                 break;
1222                 }
1223
1224         }
1225
1226         // The API specific settings of the ports are already set before
1227         // this routine is called, therefore we can init&prepare the ports
1228         if(!initPorts()) {
1229                 debugFatal("Could not initialize ports!\n");
1230                 return false;
1231         }
1232
1233         if(!preparePorts()) {
1234                 debugFatal("Could not initialize ports!\n");
1235                 return false;
1236         }
1237        
1238         return true;
1239
1240 }
1241
1242 bool MotuReceiveStreamProcessor::transfer() {
1243
1244     // the same idea as the transmit processor
1245    
1246         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n");
1247        
1248 /* another naive section:       
1249         unsigned int read_size=m_period*m_event_size;
1250         char *dummybuffer=(char *)calloc(m_period,m_event_size);
1251         if (freebob_ringbuffer_read(m_event_buffer,(char *)(dummybuffer),read_size) < read_size) {
1252                 debugWarning("Could not read from event buffer\n");
1253         }
1254
1255         receiveBlock(dummybuffer, m_period, 0);
1256
1257         free(dummybuffer);
1258 */
1259         int xrun;
1260         unsigned int offset=0;
1261        
1262         freebob_ringbuffer_data_t vec[2];
1263         // We received one period of frames from each channel.
1264         // This is period_size*m_event_size bytes.
1265         unsigned int bytes2read = m_period * m_event_size;
1266
1267         // If closedown is in progress just pretend that data's been transferred
1268         // to prevent false underrun detections on the event buffer.
1269         if (m_closedown_active)
1270                 return true;
1271
1272         /* Read events2read bytes from the ringbuffer.
1273         *  First see if it can be done in one read.  If so, ok.
1274         *  Otherwise read up to a multiple of events directly from the buffer
1275         *  then do the buffer wrap around using ringbuffer_read
1276         *  then read the remaining data directly from the buffer in a third pass
1277         *  Make sure that we cannot end up on a non-event aligned position!
1278         */
1279         while(bytes2read>0) {
1280                 unsigned int framesread=(m_period*m_event_size-bytes2read)/m_event_size;
1281                 offset=framesread;
1282                
1283                 int bytesread=0;
1284
1285                 freebob_ringbuffer_get_read_vector(m_event_buffer, vec);
1286                        
1287                 if(vec[0].len==0) { // this indicates an empty event buffer
1288                         debugError("RCV: Event buffer underrun in processor %p\n",this);
1289                         break;
1290                 }
1291                        
1292                 /* if we don't take care we will get stuck in an infinite loop
1293                 * because we align to an event boundary later
1294                 * the remaining nb of bytes in one read operation can be smaller than one event
1295                 * this can happen because the ringbuffer size is always a power of 2
1296                 */
1297                 if(vec[0].len<m_event_size) {
1298                         // use the ringbuffer function to read one event
1299                         // the read function handles wrap around
1300                         freebob_ringbuffer_read(m_event_buffer,m_tmp_event_buffer,m_event_size);
1301
1302                         xrun = receiveBlock(m_tmp_event_buffer, 1, offset);
1303                                
1304                         if(xrun<0) {
1305                                 // xrun detected
1306                                 debugError("RCV: Frame buffer overrun in processor %p\n",this);
1307                                 break;
1308                         }
1309                                
1310                         // We advanced one m_event_size
1311                         bytes2read-=m_event_size;
1312                                
1313                 } else { //
1314                        
1315                         if(bytes2read>vec[0].len) {
1316                                         // align to an event boundary
1317                                 bytesread=vec[0].len-(vec[0].len%m_event_size);
1318                         } else {
1319                                 bytesread=bytes2read;
1320                         }
1321                                
1322                         xrun = receiveBlock(vec[0].buf, bytesread/m_event_size, offset);
1323                                
1324                         if(xrun<0) {
1325                                 // xrun detected
1326                                 debugError("RCV: Frame buffer overrun in processor %p\n",this);
1327                                 break;
1328                         }
1329
1330                         freebob_ringbuffer_read_advance(m_event_buffer, bytesread);
1331                         bytes2read -= bytesread;
1332                 }
1333                        
1334                 // the bytes2read should always be event aligned
1335                 assert(bytes2read%m_event_size==0);
1336         }
1337
1338         return true;
1339 }
1340
1341 /**
1342  * \brief write received events to the port ringbuffers.
1343  */
1344 int MotuReceiveStreamProcessor::receiveBlock(char *data,
1345                                            unsigned int nevents, unsigned int offset)
1346 {
1347         int problem=0;
1348         for ( PortVectorIterator it = m_PeriodPorts.begin();
1349           it != m_PeriodPorts.end();
1350           ++it ) {
1351                 if((*it)->isDisabled()) {continue;};
1352
1353                 //FIXME: make this into a static_cast when not DEBUG?
1354                 Port *port=dynamic_cast<Port *>(*it);
1355                
1356                 switch(port->getPortType()) {
1357                
1358                 case Port::E_Audio:
1359                         if(decodeMBLAEventsToPort(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
1360                                 debugWarning("Could not decode packet MBLA to port %s",(*it)->getName().c_str());
1361                                 problem=1;
1362                         }
1363                         break;
1364                 // midi is a packet based port, don't process
1365                 //      case MotuPortInfo::E_Midi:
1366                 //              break;
1367
1368                 default: // ignore
1369                         break;
1370                 }
1371         }
1372         return problem;
1373 }
1374
1375 /**
1376  * @brief decode a packet for the packet-based ports
1377  *
1378  * @param data Packet data
1379  * @param nevents number of events in data (including events of other ports & port types)
1380  * @param dbc DataBlockCount value for this packet
1381  * @return true if all successfull
1382  */
1383 bool MotuReceiveStreamProcessor::decodePacketPorts(quadlet_t *data, unsigned int nevents,
1384                 unsigned int dbc) {
1385         bool ok=true;
1386
1387         // Use char here since the source address won't necessarily be
1388         // aligned; use of an unaligned quadlet_t may cause issues on
1389         // certain architectures.  Besides, the source for MIDI data going
1390         // directly to the MOTU isn't structured in quadlets anyway; it is a
1391         // sequence of 3 unaligned bytes.
1392         unsigned char *src = NULL;
1393
1394         for ( PortVectorIterator it = m_PacketPorts.begin();
1395                 it != m_PacketPorts.end();
1396                 ++it ) {
1397
1398                 Port *port=dynamic_cast<Port *>(*it);
1399                 assert(port); // this should not fail!!
1400
1401                 // Currently the only packet type of events for MOTU
1402                 // is MIDI in mbla.  However in future control data
1403                 // might also be sent via "packet" events, so allow
1404                 // for this possible expansion.
1405
1406                 // FIXME: MIDI input is completely untested at present.
1407                 switch (port->getPortType()) {
1408                         case Port::E_Midi: {
1409                                 MotuMidiPort *mp=static_cast<MotuMidiPort *>(*it);
1410                                 signed int sample;
1411                                 unsigned int j = 0;
1412                                 // Get MIDI bytes if present anywhere in the
1413                                 // packet.  MOTU MIDI data is sent using a
1414                                 // 3-byte sequence starting at the port's
1415                                 // position.  It's thought that there can never
1416                                 // be more than one MIDI byte per packet, but
1417                                 // for completeness we'll check the entire packet
1418                                 // anyway.
1419                                 src = (unsigned char *)data + mp->getPosition();
1420                                 while (j < nevents) {
1421                                         if (*src==0x01 && *(src+1)==0x00) {
1422                                                 sample = *(src+2);
1423                                                 if (!mp->writeEvent(&sample)) {
1424                                                         debugWarning("MIDI packet port events lost\n");
1425                                                         ok = false;
1426                                                 }
1427                                         }
1428                                         j++;
1429                                         src += m_event_size;
1430                                 }
1431                                 break;
1432                         }
1433                         default:
1434                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown packet-type port format %d\n",port->getPortType());
1435                                 return ok;       
1436                 }
1437         }
1438
1439         return ok;
1440 }
1441
1442 signed int MotuReceiveStreamProcessor::decodeMBLAEventsToPort(MotuAudioPort *p,
1443                 quadlet_t *data, unsigned int offset, unsigned int nevents)
1444 {
1445         unsigned int j=0;
1446
1447         // Use char here since a port's source address won't necessarily be
1448         // aligned; use of an unaligned quadlet_t may cause issues on
1449         // certain architectures.  Besides, the source (data coming directly
1450         // from the MOTU) isn't structured in quadlets anyway; it mainly
1451         // consists of packed 24-bit integers.
1452
1453         unsigned char *src_data;
1454         src_data = (unsigned char *)data + p->getPosition();
1455
1456         switch(p->getDataType()) {
1457                 default:
1458                 case Port::E_Int24:
1459                         {
1460                                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
1461
1462                                 assert(nevents + offset <= p->getBufferSize());
1463
1464                                 // Offset is in frames, but each port is only a single
1465                                 // channel, so the number of frames is the same as the
1466                                 // number of quadlets to offset (assuming the port buffer
1467                                 // uses one quadlet per sample, which is the case currently).
1468                                 buffer+=offset;
1469
1470                                 for(j = 0; j < nevents; j += 1) { // Decode nsamples
1471                                         *buffer = (*src_data<<16)+(*(src_data+1)<<8)+*(src_data+2);
1472                                         // Sign-extend highest bit of 24-bit int.
1473                                         // FIXME: this isn't strictly needed since E_Int24 is a 24-bit,
1474                                         // but doing so shouldn't break anything and makes the data
1475                                         // easier to deal with during debugging.
1476                                         if (*src_data & 0x80)
1477                                                 *buffer |= 0xff000000;
1478
1479                                         buffer++;
1480                                         src_data+=m_event_size;
1481                                 }
1482                         }
1483                         break;
1484                 case Port::E_Float:
1485                         {
1486                                 const float multiplier = 1.0f / (float)(0x7FFFFF);
1487                                 float *buffer=(float *)(p->getBufferAddress());
1488
1489                                 assert(nevents + offset <= p->getBufferSize());
1490
1491                                 buffer+=offset;
1492
1493                                 for(j = 0; j < nevents; j += 1) { // decode max nsamples               
1494        
1495                                         unsigned int v = (*src_data<<16)+(*(src_data+1)<<8)+*(src_data+2);
1496
1497                                         // sign-extend highest bit of 24-bit int
1498                                         int tmp = (int)(v << 8) / 256;
1499                
1500                                         *buffer = tmp * multiplier;
1501                                
1502                                         buffer++;
1503                                         src_data+=m_event_size;
1504                                 }
1505                         }
1506                         break;
1507         }
1508
1509         return 0;
1510 }
1511
1512 signed int MotuReceiveStreamProcessor::setEventSize(unsigned int size) {
1513         m_event_size = size;
1514         return 0;
1515 }
1516
1517 unsigned int MotuReceiveStreamProcessor::getEventSize(void) {
1518 //
1519 // Return the size of a single event sent by the MOTU as part of an iso
1520 // data packet in bytes.
1521 //
1522         return m_event_size;
1523 }
1524
1525 bool MotuReceiveStreamProcessor::preparedForStop() {
1526
1527         // A MOTU receive stream can stop at any time.  However, signify
1528         // that stopping is in progress because other streams (notably the
1529         // transmit stream) may keep going for some time and cause an
1530         // overflow in the receive buffers.  If a closedown is in progress
1531         // the receive handler simply throws all incoming data away so
1532         // no buffer overflow can occur.
1533         m_closedown_active = 1;
1534         return true;
1535 }
1536
1537 bool MotuReceiveStreamProcessor::preparedForStart() {
1538 // Reset some critical variables required so the stream starts cleanly. This
1539 // method is called once on every stream restart, including those during
1540 // xrun recovery.  Initialisations which should be done once should be
1541 // placed in the init() method instead.
1542         m_running = 0;
1543         m_next_cycle = -1;
1544         m_closedown_active = 0;
1545         m_last_cycle_ofs = -1;
1546
1547         // At this point we'll also disable the stream processor here.
1548         // At this stage stream processors are always explicitly re-enabled
1549         // after being started, so by starting in the disabled state we
1550         // ensure that every start will be exactly the same.
1551         disable();
1552
1553         return true;
1554 }
1555
1556                
1557 } // end of namespace FreebobStreaming
Note: See TracBrowser for help on using the browser.