root/trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp

Revision 1361, 29.6 kB (checked in by ppalmers, 15 years ago)

Merge 2.0 branch changes.

svn merge -r1349:HEAD svn+ssh://ffadosvn@ffado.org/ffado/branches/libffado-2.0

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