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

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

- temporary commit as backup measure
- rewrote synchronisation code
- receive streaming based on SYT works
- transmit streaming synced to received stream sort of works, still

have to iron out some issues.

NOTE: all devices but the bebob's are disabled in this code,

because they still have to be ported to the new sync
mechanism.

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