root/branches/libffado-2.0/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp

Revision 1487, 27.8 kB (checked in by jwoithe, 15 years ago)

MOTU: a tweak which may partially address the MOTU problems seen with jack svn >= 3100 following changes in ffado svn r1449.

Line 
1 /*
2  * Copyright (C) 2005-2008 by Jonathan Woithe
3  * Copyright (C) 2005-2008 by Pieter Palmers
4  *
5  * This file is part of FFADO
6  * FFADO = Free Firewire (pro-)audio drivers for linux
7  *
8  * FFADO is based upon FreeBoB.
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 2 of the License, or
13  * (at your option) version 3 of the License.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #include "config.h"
26 #include "libutil/float_cast.h"
27
28 #include "MotuTransmitStreamProcessor.h"
29 #include "MotuPort.h"
30 #include "../StreamProcessorManager.h"
31 #include "devicemanager.h"
32
33 #include "libieee1394/ieee1394service.h"
34 #include "libieee1394/IsoHandlerManager.h"
35 #include "libieee1394/cycletimer.h"
36
37 #include "libutil/ByteSwap.h"
38
39 #include <cstring>
40 #include <assert.h>
41
42 /* Provide more intuitive access to GCC's branch predition built-ins */
43 #define likely(x)   __builtin_expect((x),1)
44 #define unlikely(x) __builtin_expect((x),0)
45
46 namespace Streaming
47 {
48
49 // A macro to extract specific bits from a native endian quadlet
50 #define get_bits(_d,_start,_len) (((_d)>>((_start)-(_len)+1)) & ((1<<(_len))-1))
51
52 // Convert a full timestamp into an SPH timestamp as required by the MOTU
53 static inline uint32_t fullTicksToSph(int64_t timestamp) {
54     return TICKS_TO_CYCLE_TIMER(timestamp) & 0x1ffffff;
55 }
56
57 /* transmit */
58 MotuTransmitStreamProcessor::MotuTransmitStreamProcessor(FFADODevice &parent, unsigned int event_size )
59         : StreamProcessor(parent, ePT_Transmit )
60         , m_event_size( event_size )
61         , m_tx_dbc( 0 )
62         , mb_head( 0 )
63         , mb_tail( 0 )
64         , midi_lock( 0 )
65 {
66   int srate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate();
67   /* Work out how many audio samples should be left between MIDI data bytes in order
68    * to stay under the MIDI hardware baud rate of 31250.  MIDI data is transmitted
69    * using 10 bits per byte (including the start/stop bit) so this gives us 3125 bytes
70    * per second.  If we send to the MOTU at a faster rate than this, some MIDI bytes
71    * will be dropped or corrupted in interesting ways.
72    */
73   midi_tx_period = lrintf(ceil((float)srate / 3125));
74 }
75
76 unsigned int
77 MotuTransmitStreamProcessor::getMaxPacketSize() {
78     int framerate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate();
79     return framerate<=48000?616:(framerate<=96000?1032:1160);
80 }
81
82 unsigned int
83 MotuTransmitStreamProcessor::getNominalFramesPerPacket() {
84     int framerate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate();
85     return framerate<=48000?8:(framerate<=96000?16:32);
86 }
87
88 enum StreamProcessor::eChildReturnValue
89 MotuTransmitStreamProcessor::generatePacketHeader (
90     unsigned char *data, unsigned int *length,
91     unsigned char *tag, unsigned char *sy,
92     uint32_t pkt_ctr )
93 {
94     unsigned int cycle = CYCLE_TIMER_GET_CYCLES(pkt_ctr);
95
96     // The number of events per packet expected by the MOTU is solely
97     // dependent on the current sample rate.  An 'event' is one sample from
98     // all channels plus possibly other midi and control data.
99     signed n_events = getNominalFramesPerPacket();
100
101     // Do housekeeping expected for all packets sent to the MOTU, even
102     // for packets containing no audio data.
103     *sy = 0x00;
104     *tag = 1;      // All MOTU packets have a CIP-like header
105     *length = n_events*m_event_size + 8;
106
107     signed int fc;
108     uint64_t presentation_time;
109     unsigned int presentation_cycle;
110     int cycles_until_presentation;
111
112     uint64_t transmit_at_time;
113     unsigned int transmit_at_cycle;
114     int cycles_until_transmit;
115
116     debugOutput ( DEBUG_LEVEL_ULTRA_VERBOSE, "Try for cycle %d\n", cycle );
117     // check whether the packet buffer has packets for us to send.
118     // the base timestamp is the one of the next sample in the buffer
119     ffado_timestamp_t ts_head_tmp;
120     m_data_buffer->getBufferHeadTimestamp ( &ts_head_tmp, &fc ); // thread safe
121
122     // the timestamp gives us the time at which we want the sample block
123     // to be output by the device
124     presentation_time = ( uint64_t ) ts_head_tmp;
125
126     // now we calculate the time when we have to transmit the sample block
127     transmit_at_time = substractTicks ( presentation_time, MOTU_TRANSMIT_TRANSFER_DELAY );
128
129     // calculate the cycle this block should be presented in
130     // (this is just a virtual calculation since at that time it should
131     //  already be in the device's buffer)
132     presentation_cycle = ( unsigned int ) ( TICKS_TO_CYCLES ( presentation_time ) );
133
134     // calculate the cycle this block should be transmitted in
135     transmit_at_cycle = ( unsigned int ) ( TICKS_TO_CYCLES ( transmit_at_time ) );
136
137     // we can check whether this cycle is within the 'window' we have
138     // to send this packet.
139     // first calculate the number of cycles left before presentation time
140     cycles_until_presentation = diffCycles ( presentation_cycle, cycle );
141
142     // we can check whether this cycle is within the 'window' we have
143     // to send this packet.
144     // first calculate the number of cycles left before presentation time
145     cycles_until_transmit = diffCycles ( transmit_at_cycle, cycle );
146
147     // two different options:
148     // 1) there are not enough frames for one packet
149     //      => determine wether this is a problem, since we might still
150     //         have some time to send it
151     // 2) there are enough packets
152     //      => determine whether we have to send them in this packet
153     if ( fc < ( signed int ) getNominalFramesPerPacket() )
154     {
155         // not enough frames in the buffer,
156
157         // we can still postpone the queueing of the packets
158         // if we are far enough ahead of the presentation time
159         if ( cycles_until_presentation <= MOTU_MIN_CYCLES_BEFORE_PRESENTATION )
160         {
161             debugOutput ( DEBUG_LEVEL_VERBOSE,
162                         "Insufficient frames (P): N=%02d, CY=%04u, TC=%04u, CUT=%04d\n",
163                         fc, cycle, transmit_at_cycle, cycles_until_transmit );
164             // we are too late
165             return eCRV_XRun;
166         }
167         else
168         {
169             debugOutput ( DEBUG_LEVEL_VERY_VERBOSE,
170                         "Insufficient frames (NP): N=%02d, CY=%04u, TC=%04u, CUT=%04d\n",
171                         fc, cycle, transmit_at_cycle, cycles_until_transmit );
172             // there is still time left to send the packet
173             // we want the system to give this packet another go at a later time instant
174             return eCRV_Again;
175         }
176     }
177     else
178     {
179         // there are enough frames, so check the time they are intended for
180         // all frames have a certain 'time window' in which they can be sent
181         // this corresponds to the range of the timestamp mechanism:
182         // we can send a packet 15 cycles in advance of the 'presentation time'
183         // in theory we can send the packet up till one cycle before the presentation time,
184         // however this is not very smart.
185
186         // There are 3 options:
187         // 1) the frame block is too early
188         //      => send an empty packet
189         // 2) the frame block is within the window
190         //      => send it
191         // 3) the frame block is too late
192         //      => discard (and raise xrun?)
193         //         get next block of frames and repeat
194
195         if(cycles_until_transmit < 0)
196         {
197             // we are too late
198             debugOutput(DEBUG_LEVEL_VERBOSE,
199                         "Too late: CY=%04u, TC=%04u, CUT=%04d, TSP=%011llu (%04u)\n",
200                         cycle,
201                         transmit_at_cycle, cycles_until_transmit,
202                         presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time) );
203
204             // however, if we can send this sufficiently before the presentation
205             // time, it could be harmless.
206             // NOTE: dangerous since the device has no way of reporting that it didn't get
207             //       this packet on time.
208             if(cycles_until_presentation >= MOTU_MIN_CYCLES_BEFORE_PRESENTATION)
209             {
210                 // we are not that late and can still try to transmit the packet
211                 m_tx_dbc += fillDataPacketHeader((quadlet_t *)data, length, presentation_time);
212                 m_last_timestamp = presentation_time;
213                 if (m_tx_dbc > 0xff)
214                     m_tx_dbc -= 0x100;
215                 return eCRV_Packet;
216             }
217             else   // definitely too late
218             {
219                 return eCRV_XRun;
220             }
221         }
222         else if(cycles_until_transmit <= MOTU_MAX_CYCLES_TO_TRANSMIT_EARLY)
223         {
224             // it's time send the packet
225             m_tx_dbc += fillDataPacketHeader((quadlet_t *)data, length, presentation_time);
226             m_last_timestamp = presentation_time;
227             if (m_tx_dbc > 0xff)
228                 m_tx_dbc -= 0x100;
229             return eCRV_Packet;
230         }
231         else
232         {
233             debugOutput ( DEBUG_LEVEL_VERY_VERBOSE,
234                         "Too early: CY=%04u, TC=%04u, CUT=%04d, TST=%011llu (%04u), TSP=%011llu (%04u)\n",
235                         cycle,
236                         transmit_at_cycle, cycles_until_transmit,
237                         transmit_at_time, ( unsigned int ) TICKS_TO_CYCLES ( transmit_at_time ),
238                         presentation_time, ( unsigned int ) TICKS_TO_CYCLES ( presentation_time ) );
239 #ifdef DEBUG
240             if ( cycles_until_transmit > MOTU_MAX_CYCLES_TO_TRANSMIT_EARLY + 1 )
241             {
242                 debugOutput ( DEBUG_LEVEL_VERY_VERBOSE,
243                             "Way too early: CY=%04u, TC=%04u, CUT=%04d, TST=%011llu (%04u), TSP=%011llu (%04u)\n",
244                             cycle,
245                             transmit_at_cycle, cycles_until_transmit,
246                             transmit_at_time, ( unsigned int ) TICKS_TO_CYCLES ( transmit_at_time ),
247                             presentation_time, ( unsigned int ) TICKS_TO_CYCLES ( presentation_time ) );
248             }
249 #endif
250             // we are too early, send only an empty packet
251             return eCRV_EmptyPacket;
252         }
253     }
254     return eCRV_Invalid;
255 }
256
257 enum StreamProcessor::eChildReturnValue
258 MotuTransmitStreamProcessor::generatePacketData (
259     unsigned char *data, unsigned int *length)
260 {
261     quadlet_t *quadlet = (quadlet_t *)data;
262     quadlet += 2; // skip the header
263     // Size of a single data frame in quadlets
264     unsigned dbs = m_event_size / 4;
265
266     // The number of events per packet expected by the MOTU is solely
267     // dependent on the current sample rate.  An 'event' is one sample from
268     // all channels plus possibly other midi and control data.
269     signed n_events = getNominalFramesPerPacket();
270
271     if (m_data_buffer->readFrames(n_events, (char *)(data + 8))) {
272         float ticks_per_frame = m_Parent.getDeviceManager().getStreamProcessorManager().getSyncSource().getTicksPerFrame();
273
274         for (int i=0; i < n_events; i++, quadlet += dbs) {
275             int64_t ts_frame = addTicks(m_last_timestamp, (unsigned int)lrintf(i * ticks_per_frame));
276             *quadlet = CondSwapToBus32(fullTicksToSph(ts_frame));
277         }
278
279         return eCRV_OK;
280     }
281     else return eCRV_XRun;
282
283 }
284
285 enum StreamProcessor::eChildReturnValue
286 MotuTransmitStreamProcessor::generateEmptyPacketHeader (
287     unsigned char *data, unsigned int *length,
288     unsigned char *tag, unsigned char *sy,
289     uint32_t pkt_ctr )
290 {
291     debugOutput ( DEBUG_LEVEL_VERY_VERBOSE, "XMIT EMPTY: CY=%04u, TSP=%011llu (%04u)\n",
292                 CYCLE_TIMER_GET_CYCLES(pkt_ctr), m_last_timestamp,
293                 ( unsigned int ) TICKS_TO_CYCLES ( m_last_timestamp ) );
294
295     // Do housekeeping expected for all packets sent to the MOTU, even
296     // for packets containing no audio data.
297     *sy = 0x00;
298     *tag = 1;      // All MOTU packets have a CIP-like header
299     *length = 8;
300
301     m_tx_dbc += fillNoDataPacketHeader ( (quadlet_t *)data, length );
302     return eCRV_OK;
303 }
304
305 enum StreamProcessor::eChildReturnValue
306 MotuTransmitStreamProcessor::generateEmptyPacketData (
307     unsigned char *data, unsigned int *length)
308 {
309     return eCRV_OK; // no need to do anything
310 }
311
312 enum StreamProcessor::eChildReturnValue
313 MotuTransmitStreamProcessor::generateSilentPacketHeader (
314     unsigned char *data, unsigned int *length,
315     unsigned char *tag, unsigned char *sy,
316     uint32_t pkt_ctr )
317 {
318     unsigned int cycle = CYCLE_TIMER_GET_CYCLES(pkt_ctr);
319
320     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "XMIT SILENT: CY=%04u, TSP=%011llu (%04u)\n",
321                  cycle, m_last_timestamp,
322                  ( unsigned int ) TICKS_TO_CYCLES ( m_last_timestamp ) );
323
324     // A "silent" packet is identical to a regular data packet except all
325     // audio data is set to zero.  The MOTU expects valid timestamps and
326     // rate control in silent packets, so much of the timing logic from
327     // generatePacketHeader() is needed here too - the main difference being
328     // the source of the packet timestamp.
329
330     // The number of events per packet expected by the MOTU is solely
331     // dependent on the current sample rate.  An 'event' is one sample from
332     // all channels plus possibly other midi and control data.
333     signed n_events = getNominalFramesPerPacket();
334
335     // Do housekeeping expected for all packets sent to the MOTU, even
336     // for packets containing no audio data.
337     *sy = 0x00;
338     *tag = 1;      // All MOTU packets have a CIP-like header
339
340     /* Assume the packet will have audio data.  If it turns out we need an empty packet
341      * the length will be overridden by fillNoDataPacketHeader().
342      */
343     *length = n_events*m_event_size + 8;
344
345     uint64_t presentation_time;
346     unsigned int presentation_cycle;
347     int cycles_until_presentation;
348            
349     uint64_t transmit_at_time;
350     unsigned int transmit_at_cycle;
351     int cycles_until_transmit;
352
353     /* The sample buffer is not necessarily running when silent packets are
354      * needed, so use m_last_timestamp (the timestamp of the previously sent
355      * data packet) as the basis for the presentation time of the next
356      * packet.  Since we're only writing zeros we don't have to deal with
357      * buffer xruns.
358      */
359     float ticks_per_frame = m_Parent.getDeviceManager().getStreamProcessorManager().getSyncSource().getTicksPerFrame();
360     presentation_time = addTicks(m_last_timestamp, (unsigned int)lrintf(n_events * ticks_per_frame));
361
362     transmit_at_time = substractTicks(presentation_time, MOTU_TRANSMIT_TRANSFER_DELAY);
363     presentation_cycle = (unsigned int)(TICKS_TO_CYCLES(presentation_time));
364     transmit_at_cycle = (unsigned int)(TICKS_TO_CYCLES(transmit_at_time));
365     cycles_until_presentation = diffCycles(presentation_cycle, cycle);
366     cycles_until_transmit = diffCycles(transmit_at_cycle, cycle);
367
368     if (cycles_until_transmit < 0)
369     {
370         if (cycles_until_presentation >= MOTU_MIN_CYCLES_BEFORE_PRESENTATION)
371         {
372             m_last_timestamp = presentation_time;
373             m_tx_dbc += fillDataPacketHeader((quadlet_t *)data, length, m_last_timestamp);
374             if (m_tx_dbc > 0xff)
375                 m_tx_dbc -= 0x100;
376             return eCRV_Packet;
377         }
378         else
379         {
380             return eCRV_XRun;
381         }
382     }
383     else if (cycles_until_transmit <= MOTU_MAX_CYCLES_TO_TRANSMIT_EARLY)
384     {
385         m_last_timestamp = presentation_time;
386         m_tx_dbc += fillDataPacketHeader((quadlet_t *)data, length, m_last_timestamp);
387         if (m_tx_dbc > 0xff)
388             m_tx_dbc -= 0x100;
389         return eCRV_Packet;
390     }
391     else
392     {
393         return eCRV_EmptyPacket;
394     }
395     return eCRV_Invalid;
396 }
397
398 enum StreamProcessor::eChildReturnValue
399 MotuTransmitStreamProcessor::generateSilentPacketData (
400     unsigned char *data, unsigned int *length )
401 {
402     // Simply set all audio data to zero since that's what's meant by
403     // a "silent" packet.  Note that m_event_size is in bytes for MOTU.
404
405     quadlet_t *quadlet = (quadlet_t *)data;
406     quadlet += 2; // skip the header
407     // Size of a single data frame in quadlets
408     unsigned dbs = m_event_size / 4;
409
410     // The number of events per packet expected by the MOTU is solely
411     // dependent on the current sample rate.  An 'event' is one sample from
412     // all channels plus possibly other midi and control data.
413     signed n_events = getNominalFramesPerPacket();
414
415     memset(quadlet, 0, n_events*m_event_size);
416     float ticks_per_frame = m_Parent.getDeviceManager().getStreamProcessorManager().getSyncSource().getTicksPerFrame();
417
418     // Set up each frames's SPH.
419     for (int i=0; i < n_events; i++, quadlet += dbs) {
420         int64_t ts_frame = addTicks(m_last_timestamp, (unsigned int)lrintf(i * ticks_per_frame));
421         *quadlet = CondSwapToBus32(fullTicksToSph(ts_frame));
422     }
423     return eCRV_OK;
424 }
425
426 unsigned int MotuTransmitStreamProcessor::fillDataPacketHeader (
427     quadlet_t *data, unsigned int* length,
428     uint32_t ts )
429 {
430     quadlet_t *quadlet = (quadlet_t *)data;
431     // Size of a single data frame in quadlets.  For data sent TO the
432     // Ultralite this is not strictly true (with m_event_size 52, dbs is set
433     // to 13, even though data sent by the Ultralite uses 19 as one would
434     // expect from a 52-byte event).  Even so, we'll run with the assumption
435     // that a different dbs will be fine unless proven otherwise.
436     unsigned dbs = m_event_size / 4;
437
438     // The number of events per packet expected by the MOTU is solely
439     // dependent on the current sample rate.  An 'event' is one sample from
440     // all channels plus possibly other midi and control data.
441     signed n_events = getNominalFramesPerPacket();
442
443     // construct the packet CIP-like header.  Even if this is a data-less
444     // packet the dbs field is still set as if there were data blocks
445     // present.  For data-less packets the dbc is the same as the previously
446     // transmitted block.
447     *quadlet = CondSwapToBus32(0x00000400 | ((m_Parent.get1394Service().getLocalNodeId()&0x3f)<<24) | m_tx_dbc | (dbs<<16));
448     quadlet++;
449     *quadlet = CondSwapToBus32(0x8222ffff);
450     quadlet++;
451     return n_events;
452 }
453
454 unsigned int MotuTransmitStreamProcessor::fillNoDataPacketHeader (
455     quadlet_t *data, unsigned int* length )
456 {
457     quadlet_t *quadlet = (quadlet_t *)data;
458     // Size of a single data frame in quadlets.  See comment in
459     // fillDataPacketHeader() regarding the Ultralite.
460     unsigned dbs = m_event_size / 4;
461     // construct the packet CIP-like header.  Even if this is a data-less
462     // packet the dbs field is still set as if there were data blocks
463     // present.  For data-less packets the dbc is the same as the previously
464     // transmitted block.
465     *quadlet = CondSwapToBus32(0x00000400 | ((m_Parent.get1394Service().getLocalNodeId()&0x3f)<<24) | m_tx_dbc | (dbs<<16));
466     quadlet++;
467     *quadlet = CondSwapToBus32(0x8222ffff);
468     quadlet++;
469     *length = 8;
470     return 0;
471 }
472
473 bool MotuTransmitStreamProcessor::prepareChild()
474 {
475     debugOutput ( DEBUG_LEVEL_VERBOSE, "Preparing (%p)...\n", this );
476     return true;
477 }
478
479 /*
480 * compose the event streams for the packets from the port buffers
481 */
482 bool MotuTransmitStreamProcessor::processWriteBlock(char *data,
483                        unsigned int nevents, unsigned int offset) {
484     bool no_problem=true;
485     unsigned int i;
486
487     // Start with MIDI and control streams all zeroed.  Due to the sparce nature
488     // of these streams it is best to simply fill them in on an as-needs basis.
489     for (i=0; i<nevents; i++) {
490         memset(data+4+i*m_event_size, 0x00, 6);
491     }
492
493     for ( PortVectorIterator it = m_Ports.begin();
494       it != m_Ports.end();
495       ++it ) {
496         // If this port is disabled, don't process it
497         // if((*it)->isDisabled()) {continue;};
498
499         Port *port=(*it);
500
501         switch(port->getPortType()) {
502
503         case Port::E_Audio:
504             if (encodePortToMotuEvents(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
505                 debugWarning("Could not encode port %s to Motu events",(*it)->getName().c_str());
506                 no_problem=false;
507             }
508             break;
509         case Port::E_Midi:
510              if (encodePortToMotuMidiEvents(static_cast<MotuMidiPort *>(*it), (quadlet_t *)data, offset, nevents)) {
511                  debugWarning("Could not encode port %s to Midi events",(*it)->getName().c_str());
512                  no_problem=false;
513              }
514             break;
515         default: // ignore
516             break;
517         }
518     }
519     return no_problem;
520 }
521
522 bool
523 MotuTransmitStreamProcessor::transmitSilenceBlock(char *data,
524                        unsigned int nevents, unsigned int offset) {
525     // This is the same as the non-silence version, except that is
526     // doesn't read from the port buffers.
527     bool no_problem = true;
528     for ( PortVectorIterator it = m_Ports.begin();
529       it != m_Ports.end();
530       ++it ) {
531         Port *port=(*it);
532
533         switch(port->getPortType()) {
534
535         case Port::E_Audio:
536             if (encodeSilencePortToMotuEvents(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
537                 debugWarning("Could not encode port %s to MBLA events",(*it)->getName().c_str());
538                 no_problem = false;
539             }
540             break;
541         case Port::E_Midi:
542             if (encodeSilencePortToMotuMidiEvents(static_cast<MotuMidiPort *>(*it), (quadlet_t *)data, offset, nevents)) {
543                 debugWarning("Could not encode port %s to Midi events",(*it)->getName().c_str());
544                 no_problem = false;
545             }
546             break;
547         default: // ignore
548             break;
549         }
550     }
551     return no_problem;
552 }
553
554 int MotuTransmitStreamProcessor::encodePortToMotuEvents(MotuAudioPort *p, quadlet_t *data,
555                        unsigned int offset, unsigned int nevents) {
556 // Encodes nevents worth of data from the given port into the given buffer.  The
557 // format of the buffer is precisely that which will be sent to the MOTU.
558 // The basic idea:
559 //   iterate over the ports
560 //     * get port buffer address
561 //     * loop over events
562 //         - pick right sample in event based upon PortInfo
563 //         - convert sample from Port format (E_Int24, E_Float, ..) to MOTU
564 //           native format
565 //
566 // We include the ability to start the transfer from the given offset within
567 // the port (expressed in frames) so the 'efficient' transfer method can be
568 // utilised.
569
570     unsigned int j=0;
571
572     // Use char here since the target address won't necessarily be
573     // aligned; use of an unaligned quadlet_t may cause issues on certain
574     // architectures.  Besides, the target (data going directly to the MOTU)
575     // isn't structured in quadlets anyway; it mainly consists of packed
576     // 24-bit integers.
577     unsigned char *target;
578     target = (unsigned char *)data + p->getPosition();
579
580     switch(m_StreamProcessorManager.getAudioDataType()) {
581         default:
582         case StreamProcessorManager::eADT_Int24:
583             {
584                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
585
586                 assert(nevents + offset <= p->getBufferSize());
587
588                 // Offset is in frames, but each port is only a single
589                 // channel, so the number of frames is the same as the
590                 // number of quadlets to offset (assuming the port buffer
591                 // uses one quadlet per sample, which is the case currently).
592                 buffer+=offset;
593
594                 for(j = 0; j < nevents; j += 1) { // Decode nsamples
595                     *target = (*buffer >> 16) & 0xff;
596                     *(target+1) = (*buffer >> 8) & 0xff;
597                     *(target+2) = (*buffer) & 0xff;
598
599                     buffer++;
600                     target+=m_event_size;
601                 }
602             }
603             break;
604         case StreamProcessorManager::eADT_Float:
605             {
606                 const float multiplier = (float)(0x7FFFFF);
607                 float *buffer=(float *)(p->getBufferAddress());
608
609                 assert(nevents + offset <= p->getBufferSize());
610
611                 buffer+=offset;
612
613                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
614                     float in = *buffer;
615 #if MOTU_CLIP_FLOATS
616                     if (unlikely(in > 1.0)) in = 1.0;
617                     if (unlikely(in < -1.0)) in = -1.0;
618 #endif
619                     unsigned int v = lrintf(in * multiplier);
620                     *target = (v >> 16) & 0xff;
621                     *(target+1) = (v >> 8) & 0xff;
622                     *(target+2) = v & 0xff;
623
624                     buffer++;
625                     target+=m_event_size;
626                 }
627             }
628             break;
629     }
630
631     return 0;
632 }
633
634 int MotuTransmitStreamProcessor::encodeSilencePortToMotuEvents(MotuAudioPort *p, quadlet_t *data,
635                        unsigned int offset, unsigned int nevents) {
636     unsigned int j=0;
637     unsigned char *target = (unsigned char *)data + p->getPosition();
638
639     switch (m_StreamProcessorManager.getAudioDataType()) {
640     default:
641         case StreamProcessorManager::eADT_Int24:
642         case StreamProcessorManager::eADT_Float:
643         for (j = 0; j < nevents; j++) {
644             *target = *(target+1) = *(target+2) = 0;
645             target += m_event_size;
646         }
647         break;
648     }
649
650     return 0;
651 }
652
653 int MotuTransmitStreamProcessor::encodePortToMotuMidiEvents(
654                        MotuMidiPort *p, quadlet_t *data,
655                        unsigned int offset, unsigned int nevents) {
656
657     unsigned int j;
658     quadlet_t *src = (quadlet_t *)p->getBufferAddress();
659     src += offset;
660     unsigned char *target = (unsigned char *)data + p->getPosition();
661
662     // Send a MIDI byte if there is one to send.  MOTU MIDI data is sent using
663     // a 3-byte sequence within a frame starting at the port's position.
664     // A non-zero MSB indicates there is MIDI data to send.
665
666     for (j=0; j<nevents; j++, src++, target+=m_event_size) {
667         if (midi_lock)
668             midi_lock--;
669
670         /* FFADO's MIDI subsystem dictates that at the most there will be one
671          * MIDI byte every 8th's sample, making a MIDI byte "unlikely".
672          */
673         if (unlikely(*src & 0xff000000)) {
674             /* A MIDI byte is ready to send - buffer it */
675             midibuffer[mb_head++] = *src;
676             mb_head &= MIDIBUFFER_SIZE-1;
677             if (unlikely(mb_head == mb_tail)) {
678             /* Buffer overflow - dump oldest byte. */
679             /* Ideally this would dump an entire MIDI message, but this is only
680              * feasible if it's possible to determine the message size easily.
681              */
682                 mb_tail = (mb_tail+1) & (MIDIBUFFER_SIZE-1);
683                 debugWarning("MOTU MIDI buffer overflow\n");
684             }
685             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Buffered MIDI byte %d\n", *src & 0xff);
686         }
687
688         /* Send the MIDI byte at the tail of the buffer if enough time has elapsed
689          * since the last MIDI byte was sent.  For most iterations through the loop
690          * this condition will be false.
691          */
692         if (unlikely(mb_head!=mb_tail && !midi_lock)) {
693             *(target) = 0x01;
694             *(target+1) = 0x00;
695             *(target+2) = midibuffer[mb_tail] & 0xff;
696             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Sent MIDI byte %d (j=%d)\n", midibuffer[mb_tail], j);
697             mb_tail = (mb_tail+1) & (MIDIBUFFER_SIZE-1);
698             midi_lock = midi_tx_period;
699         }
700     }
701
702     return 0;
703 }
704
705 int MotuTransmitStreamProcessor::encodeSilencePortToMotuMidiEvents(
706                        MotuMidiPort *p, quadlet_t *data,
707                        unsigned int offset, unsigned int nevents) {
708
709     unsigned int j;
710     unsigned char *target = (unsigned char *)data + p->getPosition();
711
712     // For now, a "silent" MIDI event contains nothing but zeroes.  This
713     // may have to change if we find this isn't for some reason appropriate.
714     for (j=0; j<nevents; j++, target+=m_event_size) {
715        memset(target, 0, 3);
716     }
717
718     return 0;
719 }
720
721 } // end of namespace Streaming
Note: See TracBrowser for help on using the browser.