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

Revision 1489, 28.1 kB (checked in by jwoithe, 12 years ago)

MOTU: fix a silly typo in the last commit.

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, unconditionally send it silence.
497         if((*it)->isDisabled()) {
498           if (encodeSilencePortToMotuEvents(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
499             debugWarning("Could not encode silence for disabled port %s to Motu events\n",(*it)->getName().c_str());
500             // Don't treat this as a fatal error at this point
501           }
502           continue;
503         }
504
505         Port *port=(*it);
506
507         switch(port->getPortType()) {
508
509         case Port::E_Audio:
510             if (encodePortToMotuEvents(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
511                 debugWarning("Could not encode port %s to Motu events\n",(*it)->getName().c_str());
512                 no_problem=false;
513             }
514             break;
515         case Port::E_Midi:
516              if (encodePortToMotuMidiEvents(static_cast<MotuMidiPort *>(*it), (quadlet_t *)data, offset, nevents)) {
517                  debugWarning("Could not encode port %s to Midi events\n",(*it)->getName().c_str());
518                  no_problem=false;
519              }
520             break;
521         default: // ignore
522             break;
523         }
524     }
525     return no_problem;
526 }
527
528 bool
529 MotuTransmitStreamProcessor::transmitSilenceBlock(char *data,
530                        unsigned int nevents, unsigned int offset) {
531     // This is the same as the non-silence version, except that is
532     // doesn't read from the port buffers.
533     bool no_problem = true;
534     for ( PortVectorIterator it = m_Ports.begin();
535       it != m_Ports.end();
536       ++it ) {
537         Port *port=(*it);
538
539         switch(port->getPortType()) {
540
541         case Port::E_Audio:
542             if (encodeSilencePortToMotuEvents(static_cast<MotuAudioPort *>(*it), (quadlet_t *)data, offset, nevents)) {
543                 debugWarning("Could not encode port %s to MBLA events\n",(*it)->getName().c_str());
544                 no_problem = false;
545             }
546             break;
547         case Port::E_Midi:
548             if (encodeSilencePortToMotuMidiEvents(static_cast<MotuMidiPort *>(*it), (quadlet_t *)data, offset, nevents)) {
549                 debugWarning("Could not encode port %s to Midi events\n",(*it)->getName().c_str());
550                 no_problem = false;
551             }
552             break;
553         default: // ignore
554             break;
555         }
556     }
557     return no_problem;
558 }
559
560 int MotuTransmitStreamProcessor::encodePortToMotuEvents(MotuAudioPort *p, quadlet_t *data,
561                        unsigned int offset, unsigned int nevents) {
562 // Encodes nevents worth of data from the given port into the given buffer.  The
563 // format of the buffer is precisely that which will be sent to the MOTU.
564 // The basic idea:
565 //   iterate over the ports
566 //     * get port buffer address
567 //     * loop over events
568 //         - pick right sample in event based upon PortInfo
569 //         - convert sample from Port format (E_Int24, E_Float, ..) to MOTU
570 //           native format
571 //
572 // We include the ability to start the transfer from the given offset within
573 // the port (expressed in frames) so the 'efficient' transfer method can be
574 // utilised.
575
576     unsigned int j=0;
577
578     // Use char here since the target address won't necessarily be
579     // aligned; use of an unaligned quadlet_t may cause issues on certain
580     // architectures.  Besides, the target (data going directly to the MOTU)
581     // isn't structured in quadlets anyway; it mainly consists of packed
582     // 24-bit integers.
583     unsigned char *target;
584     target = (unsigned char *)data + p->getPosition();
585
586     switch(m_StreamProcessorManager.getAudioDataType()) {
587         default:
588         case StreamProcessorManager::eADT_Int24:
589             {
590                 quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress());
591
592                 assert(nevents + offset <= p->getBufferSize());
593
594                 // Offset is in frames, but each port is only a single
595                 // channel, so the number of frames is the same as the
596                 // number of quadlets to offset (assuming the port buffer
597                 // uses one quadlet per sample, which is the case currently).
598                 buffer+=offset;
599
600                 for(j = 0; j < nevents; j += 1) { // Decode nsamples
601                     *target = (*buffer >> 16) & 0xff;
602                     *(target+1) = (*buffer >> 8) & 0xff;
603                     *(target+2) = (*buffer) & 0xff;
604
605                     buffer++;
606                     target+=m_event_size;
607                 }
608             }
609             break;
610         case StreamProcessorManager::eADT_Float:
611             {
612                 const float multiplier = (float)(0x7FFFFF);
613                 float *buffer=(float *)(p->getBufferAddress());
614
615                 assert(nevents + offset <= p->getBufferSize());
616
617                 buffer+=offset;
618
619                 for(j = 0; j < nevents; j += 1) { // decode max nsamples
620                     float in = *buffer;
621 #if MOTU_CLIP_FLOATS
622                     if (unlikely(in > 1.0)) in = 1.0;
623                     if (unlikely(in < -1.0)) in = -1.0;
624 #endif
625                     unsigned int v = lrintf(in * multiplier);
626                     *target = (v >> 16) & 0xff;
627                     *(target+1) = (v >> 8) & 0xff;
628                     *(target+2) = v & 0xff;
629
630                     buffer++;
631                     target+=m_event_size;
632                 }
633             }
634             break;
635     }
636
637     return 0;
638 }
639
640 int MotuTransmitStreamProcessor::encodeSilencePortToMotuEvents(MotuAudioPort *p, quadlet_t *data,
641                        unsigned int offset, unsigned int nevents) {
642     unsigned int j=0;
643     unsigned char *target = (unsigned char *)data + p->getPosition();
644
645     switch (m_StreamProcessorManager.getAudioDataType()) {
646     default:
647         case StreamProcessorManager::eADT_Int24:
648         case StreamProcessorManager::eADT_Float:
649         for (j = 0; j < nevents; j++) {
650             *target = *(target+1) = *(target+2) = 0;
651             target += m_event_size;
652         }
653         break;
654     }
655
656     return 0;
657 }
658
659 int MotuTransmitStreamProcessor::encodePortToMotuMidiEvents(
660                        MotuMidiPort *p, quadlet_t *data,
661                        unsigned int offset, unsigned int nevents) {
662
663     unsigned int j;
664     quadlet_t *src = (quadlet_t *)p->getBufferAddress();
665     src += offset;
666     unsigned char *target = (unsigned char *)data + p->getPosition();
667
668     // Send a MIDI byte if there is one to send.  MOTU MIDI data is sent using
669     // a 3-byte sequence within a frame starting at the port's position.
670     // A non-zero MSB indicates there is MIDI data to send.
671
672     for (j=0; j<nevents; j++, src++, target+=m_event_size) {
673         if (midi_lock)
674             midi_lock--;
675
676         /* FFADO's MIDI subsystem dictates that at the most there will be one
677          * MIDI byte every 8th's sample, making a MIDI byte "unlikely".
678          */
679         if (unlikely(*src & 0xff000000)) {
680             /* A MIDI byte is ready to send - buffer it */
681             midibuffer[mb_head++] = *src;
682             mb_head &= MIDIBUFFER_SIZE-1;
683             if (unlikely(mb_head == mb_tail)) {
684             /* Buffer overflow - dump oldest byte. */
685             /* Ideally this would dump an entire MIDI message, but this is only
686              * feasible if it's possible to determine the message size easily.
687              */
688                 mb_tail = (mb_tail+1) & (MIDIBUFFER_SIZE-1);
689                 debugWarning("MOTU MIDI buffer overflow\n");
690             }
691             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Buffered MIDI byte %d\n", *src & 0xff);
692         }
693
694         /* Send the MIDI byte at the tail of the buffer if enough time has elapsed
695          * since the last MIDI byte was sent.  For most iterations through the loop
696          * this condition will be false.
697          */
698         if (unlikely(mb_head!=mb_tail && !midi_lock)) {
699             *(target) = 0x01;
700             *(target+1) = 0x00;
701             *(target+2) = midibuffer[mb_tail] & 0xff;
702             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Sent MIDI byte %d (j=%d)\n", midibuffer[mb_tail], j);
703             mb_tail = (mb_tail+1) & (MIDIBUFFER_SIZE-1);
704             midi_lock = midi_tx_period;
705         }
706     }
707
708     return 0;
709 }
710
711 int MotuTransmitStreamProcessor::encodeSilencePortToMotuMidiEvents(
712                        MotuMidiPort *p, quadlet_t *data,
713                        unsigned int offset, unsigned int nevents) {
714
715     unsigned int j;
716     unsigned char *target = (unsigned char *)data + p->getPosition();
717
718     // For now, a "silent" MIDI event contains nothing but zeroes.  This
719     // may have to change if we find this isn't for some reason appropriate.
720     for (j=0; j<nevents; j++, target+=m_event_size) {
721        memset(target, 0, 3);
722     }
723
724     return 0;
725 }
726
727 } // end of namespace Streaming
Note: See TracBrowser for help on using the browser.