root/branches/libfreebob-2.0/src/motu/motu_avdevice.cpp

Revision 312, 28.2 kB (checked in by jwoithe, 16 years ago)

MOTU: fix xrun recovery glitches inadvertantly introduced in r309.
MOTU: preliminary MIDI port support. Rate control still needs to be added so it probably won't work in its current form yet. MIDI has not yet been tested.
MOTU: tweaks to receive/transmit missed cycle detection.
jack driver: during driver shutdown don't try to free NULL ports created for non-audio ports during initialisation to preserve device port index locations.

Line 
1 /* motu_avdevice.cpp
2  * Copyright (C) 2006 by Pieter Palmers
3  * Copyright (C) 2006 by Jonathan Woithe
4  *
5  * This file is part of FreeBob.
6  *
7  * FreeBob is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  * FreeBob is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with FreeBob; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19  * MA 02111-1307 USA.
20  */
21
22 #include "motu/motu_avdevice.h"
23 #include "configrom.h"
24
25 #include "libfreebobavc/ieee1394service.h"
26 #include "libfreebobavc/avc_definitions.h"
27
28 #include "debugmodule/debugmodule.h"
29
30 #include "libstreaming/MotuStreamProcessor.h"
31 #include "libstreaming/MotuPort.h"
32
33 #include "libutil/DelayLockedLoop.h"
34
35 #include <string>
36 #include <stdint.h>
37 #include <assert.h>
38 #include <netinet/in.h>
39
40 #include <libraw1394/csr.h>
41
42 namespace Motu {
43
44 IMPL_DEBUG_MODULE( MotuDevice, MotuDevice, DEBUG_LEVEL_NORMAL );
45
46 char *motufw_modelname[] = {"[unknown]","828MkII", "Traveler"};
47
48 /* ======================================================================= */
49 /* Provide a mechanism for allocating iso channels and bandwidth to MOTU
50  * interfaces.
51  */
52
53 static signed int allocate_iso_channel(raw1394handle_t handle) {
54 /*
55  * Allocates an iso channel for use by the interface in a similar way to
56  * libiec61883.  Returns -1 on error (due to there being no free channels)
57  * or an allocated channel number.
58  * FIXME: As in libiec61883, channel 63 is not requested; this is either a
59  * bug or it's omitted since that's the channel preferred by video devices.
60  */
61         int c = -1;
62         for (c = 0; c < 63; c++)
63                 if (raw1394_channel_modify (handle, c, RAW1394_MODIFY_ALLOC) == 0)
64                         break;
65         if (c < 63)
66                 return c;
67         return -1;
68 }
69
70 static signed int free_iso_channel(raw1394handle_t handle, signed int channel) {
71 /*
72  * Deallocates an iso channel.  Returns -1 on error or 0 on success.  Silently
73  * ignores a request to deallocate a negative channel number.
74  */
75         if (channel < 0)
76                 return 0;
77         if (raw1394_channel_modify (handle, channel, RAW1394_MODIFY_FREE)!=0)
78                 return -1;
79         return 0;
80 }
81
82 static signed int get_iso_bandwidth_avail(raw1394handle_t handle) {
83 /*
84  * Returns the current value of the `bandwidth available' register on
85  * the IRM, or -1 on error.
86  */
87 quadlet_t buffer;
88 signed int result = raw1394_read (handle, raw1394_get_irm_id (handle),
89         CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE,
90         sizeof (quadlet_t), &buffer);
91
92         if (result < 0)
93                 return -1;
94         return ntohl(buffer);
95 }
96 /* ======================================================================= */
97
98 MotuDevice::MotuDevice( Ieee1394Service& ieee1394service,
99                         int nodeId,
100                         int verboseLevel )
101     : m_1394Service( &ieee1394service )
102     , m_motu_model( MOTUFW_MODEL_NONE )
103     , m_nodeId( nodeId )
104     , m_verboseLevel( verboseLevel )
105     , m_id(0)
106     , m_iso_recv_channel ( -1 )
107     , m_iso_send_channel ( -1 )
108     , m_bandwidth ( -1 )
109     , m_receiveProcessor ( 0 )
110     , m_transmitProcessor ( 0 )
111    
112 {
113     if ( m_verboseLevel ) {
114         setDebugLevel( DEBUG_LEVEL_VERBOSE );
115     }
116     debugOutput( DEBUG_LEVEL_VERBOSE, "Created Motu::MotuDevice (NodeID %d)\n",
117                  nodeId );
118     m_configRom = new ConfigRom( m_1394Service, m_nodeId );
119     m_configRom->initialize();
120
121 }
122
123 MotuDevice::~MotuDevice()
124 {
125         // Free ieee1394 bus resources if they have been allocated
126         if (m_1394Service != NULL) {
127                 raw1394handle_t handle = m_1394Service->getHandle();
128                 if (m_bandwidth >= 0)
129                         if (raw1394_bandwidth_modify(handle, m_bandwidth, RAW1394_MODIFY_FREE) < 0)
130                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free bandwidth of %d\n", m_bandwidth);
131                 if (m_iso_recv_channel >= 0)
132                         if (raw1394_channel_modify(handle, m_iso_recv_channel, RAW1394_MODIFY_FREE) < 0)
133                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free recv iso channel %d\n", m_iso_recv_channel);
134                 if (m_iso_send_channel >= 0)
135                         if (raw1394_channel_modify(handle, m_iso_send_channel, RAW1394_MODIFY_FREE) < 0)
136                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free send iso channel %d\n", m_iso_send_channel);
137         }
138         delete m_configRom;
139 }
140
141 ConfigRom&
142 MotuDevice::getConfigRom() const
143 {
144     return *m_configRom;
145 }
146
147 bool
148 MotuDevice::discover()
149 {
150         // Find out if this device is one we know about
151         if (m_configRom->getUnitSpecifierId() == MOTUFW_VENDOR_MOTU) {
152                 switch (m_configRom->getUnitVersion()) {
153                     case MOTUFW_UNITVER_828mkII:
154                         m_motu_model = MOTUFW_MODEL_828mkII;
155                         break;
156                     case MOTUFW_UNITVER_TRAVELER:
157                         m_motu_model = MOTUFW_MODEL_TRAVELER;
158                         break;
159                 }
160         }
161         if (m_motu_model != MOTUFW_MODEL_NONE) {
162                 debugOutput( DEBUG_LEVEL_VERBOSE, "found MOTU %s\n",
163                         motufw_modelname[m_motu_model]);
164                 return true;
165         }
166
167         return false;
168 }
169
170 int
171 MotuDevice::getSamplingFrequency( ) {
172 /*
173  * Retrieve the current sample rate from the MOTU device.
174  */
175         quadlet_t q = ReadRegister(MOTUFW_REG_CLK_CTRL);
176         int rate = 0;
177
178         switch (q & MOTUFW_RATE_BASE_MASK) {
179                 case MOTUFW_RATE_BASE_44100:
180                         rate = 44100;
181                         break;
182                 case MOTUFW_RATE_BASE_48000:
183                         rate = 48000;
184                         break;
185         }
186         switch (q & MOTUFW_RATE_MULTIPLIER_MASK) {
187                 case MOTUFW_RATE_MULTIPLIER_2X:
188                         rate *= 2;
189                         break;
190                 case MOTUFW_RATE_MULTIPLIER_4X:
191                         rate *= 4;
192                         break;
193         }
194         return rate;
195 }
196
197 bool
198 MotuDevice::setSamplingFrequency( ESamplingFrequency samplingFrequency )
199 {
200 /*
201  * Set the MOTU device's samplerate.
202  */
203         char *src_name;
204         quadlet_t q, new_rate=0;
205         int i, supported=true, cancel_adat=false;
206
207         switch ( samplingFrequency ) {
208                 case eSF_22050Hz:
209                         supported=false;
210                         break;
211                 case eSF_24000Hz:
212                         supported=false;
213                         break;
214                 case eSF_32000Hz:
215                         supported=false;
216                         break;
217                 case eSF_44100Hz:
218                         new_rate = MOTUFW_RATE_BASE_44100 | MOTUFW_RATE_MULTIPLIER_1X;
219                         break;
220                 case eSF_48000Hz:
221                         new_rate = MOTUFW_RATE_BASE_48000 | MOTUFW_RATE_MULTIPLIER_1X;
222                         break;
223                 case eSF_88200Hz:
224                         new_rate = MOTUFW_RATE_BASE_44100 | MOTUFW_RATE_MULTIPLIER_2X;
225                         break;
226                 case eSF_96000Hz:
227                         new_rate = MOTUFW_RATE_BASE_48000 | MOTUFW_RATE_MULTIPLIER_2X;
228                         break;
229                 case eSF_176400Hz:
230                         // Currently only the Traveler supports 4x sample rates
231                         if (m_motu_model == MOTUFW_MODEL_TRAVELER) {
232                                 new_rate = MOTUFW_RATE_BASE_44100 | MOTUFW_RATE_MULTIPLIER_4X;
233                                 cancel_adat = true;
234                         } else
235                                 supported=false;
236                         break;
237                 case eSF_192000Hz:
238                         // Currently only the Traveler supports 4x sample rates
239                         if (m_motu_model == MOTUFW_MODEL_TRAVELER) {
240                                 new_rate = MOTUFW_RATE_BASE_48000 | MOTUFW_RATE_MULTIPLIER_4X;
241                                 cancel_adat = true;
242                         } else
243                                 supported=false;
244                         break;
245                 default:
246                         supported=false;
247         }
248
249         // Update the clock control register.  FIXME: while this is now rather
250         // comprehensive there may still be a need to manipulate MOTUFW_REG_CLK_CTRL
251         // a little more than we do.
252         if (supported) {
253                 quadlet_t value=ReadRegister(MOTUFW_REG_CLK_CTRL);
254
255                 // If optical port must be disabled (because a 4x sample rate has
256                 // been selected) then do so before changing the sample rate.  At
257                 // this stage it will be up to the user to re-enable the optical
258                 // port if the sample rate is set to a 1x or 2x rate later.
259                 if (cancel_adat) {
260                         setOpticalMode(MOTUFW_DIR_INOUT, MOTUFW_OPTICAL_MODE_OFF);
261                 }
262
263                 value &= ~(MOTUFW_RATE_BASE_MASK|MOTUFW_RATE_MULTIPLIER_MASK);
264                 value |= new_rate;
265
266                 // In other OSes bit 26 of MOTUFW_REG_CLK_CTRL always seems
267                 // to be set when this register is written to although the
268                 // reason isn't currently known.  When we set it, it appears
269                 // to prevent output being produced so we'll leave it unset
270                 // until we work out what's going on.  Other systems write
271                 // to MOTUFW_REG_CLK_CTRL multiple times, so that may be
272                 // part of the mystery.
273                 //   value |= 0x04000000;
274                 if (WriteRegister(MOTUFW_REG_CLK_CTRL, value) == 0) {
275                         supported=true;
276                 } else {
277                         supported=false;
278                 }
279                 // A write to the rate/clock control register requires the
280                 // textual name of the current clock source be sent to the
281                 // clock source name registers.
282                 switch (value & MOTUFW_CLKSRC_MASK) {
283                         case MOTUFW_CLKSRC_INTERNAL:
284                                 src_name = "Internal        ";
285                                 break;
286                         case MOTUFW_CLKSRC_ADAT_OPTICAL:
287                                 src_name = "ADAT Optical    ";
288                                 break;
289                         case MOTUFW_CLKSRC_SPDIF_TOSLINK:
290                                 if (getOpticalMode(MOTUFW_DIR_IN)  == MOTUFW_OPTICAL_MODE_TOSLINK)
291                                         src_name = "TOSLink         ";
292                                 else
293                                         src_name = "SPDIF           ";
294                                 break;
295                         case MOTUFW_CLKSRC_SMTPE:
296                                 src_name = "SMPTE           ";
297                                 break;
298                         case MOTUFW_CLKSRC_WORDCLOCK:
299                                 src_name = "Word Clock In   ";
300                                 break;
301                         case MOTUFW_CLKSRC_ADAT_9PIN:
302                                 src_name = "ADAT 9-pin      ";
303                                 break;
304                         case MOTUFW_CLKSRC_AES_EBU:
305                                 src_name = "AES-EBU         ";
306                                 break;
307                         default:
308                                 src_name = "Unknown         ";
309                 }
310                 for (i=0; i<16; i+=4) {
311                         q = (src_name[i]<<24) | (src_name[i+1]<<16) |
312                                 (src_name[i+2]<<8) | src_name[i+3];
313                         WriteRegister(MOTUFW_REG_CLKSRC_NAME0+i, q);
314                 }
315         }
316         return supported;
317 }
318
319 bool MotuDevice::setId( unsigned int id) {
320         debugOutput( DEBUG_LEVEL_VERBOSE, "Set id to %d...\n", id);
321         m_id=id;
322         return true;
323 }
324
325 void
326 MotuDevice::showDevice() const
327 {
328         debugOutput(DEBUG_LEVEL_VERBOSE,
329                 "MOTU %s at node %d\n", motufw_modelname[m_motu_model],
330                 m_nodeId);
331 }
332
333 bool
334 MotuDevice::prepare() {
335
336         int samp_freq = getSamplingFrequency();
337         unsigned int optical_in_mode = getOpticalMode(MOTUFW_DIR_IN);
338         unsigned int optical_out_mode = getOpticalMode(MOTUFW_DIR_OUT);
339         unsigned int event_size_in = getEventSize(MOTUFW_DIR_IN);
340         unsigned int event_size_out= getEventSize(MOTUFW_DIR_OUT);
341
342         raw1394handle_t handle = m_1394Service->getHandle();
343
344         debugOutput(DEBUG_LEVEL_NORMAL, "Preparing MotuDevice...\n" );
345
346         // Assign iso channels if not already done
347         if (m_iso_recv_channel < 0)
348                 m_iso_recv_channel = allocate_iso_channel(handle);
349         if (m_iso_send_channel < 0)
350                 m_iso_send_channel = allocate_iso_channel(handle);
351
352         debugOutput(DEBUG_LEVEL_VERBOSE, "recv channel = %d, send channel = %d\n",
353                 m_iso_recv_channel, m_iso_send_channel);
354
355         if (m_iso_recv_channel<0 || m_iso_send_channel<0) {
356                 debugFatal("Could not allocate iso channels!\n");
357                 return false;
358         }
359
360         // Allocate bandwidth if not previously done.
361         // FIXME: The bandwidth allocation calculation can probably be
362         // refined somewhat since this is currently based on a rudimentary
363         // understanding of the iso protocol.
364         // Currently we assume the following.
365         //   * Ack/iso gap = 0.05 us
366         //   * DATA_PREFIX = 0.16 us
367         //   * DATA_END    = 0.26 us
368         // These numbers are the worst-case figures given in the ieee1394
369         // standard.  This gives approximately 0.5 us of overheads per
370         // packet - around 25 bandwidth allocation units (from the ieee1394
371         // standard 1 bandwidth allocation unit is 125/6144 us).  We further
372         // assume the MOTU is running at S400 (which it should be) so one
373         // allocation unit is equivalent to 1 transmitted byte; thus the
374         // bandwidth allocation required for the packets themselves is just
375         // the size of the packet.  We allocate based on the maximum packet
376         // size (1160 bytes at 192 kHz) so the sampling frequency can be
377         // changed dynamically if this ends up being useful in future.
378         m_bandwidth = 25 + 1160;
379         debugOutput(DEBUG_LEVEL_VERBOSE, "Available bandwidth: %d\n",
380                 get_iso_bandwidth_avail(handle));
381         if (raw1394_bandwidth_modify(handle, m_bandwidth, RAW1394_MODIFY_ALLOC) < 0) {
382                 debugFatal("Could not allocate bandwidth of %d\n", m_bandwidth);
383                 m_bandwidth = -1;
384                 return false;
385         }
386         debugOutput(DEBUG_LEVEL_VERBOSE,
387                 "allocated bandwidth of %d for MOTU device\n", m_bandwidth);
388         debugOutput(DEBUG_LEVEL_VERBOSE,
389                 "remaining bandwidth: %d\n", get_iso_bandwidth_avail(handle));
390
391         m_receiveProcessor=new FreebobStreaming::MotuReceiveStreamProcessor(
392                 m_1394Service->getPort(), samp_freq, event_size_in);
393
394         // The first thing is to initialize the processor.  This creates the
395         // data structures.
396         if(!m_receiveProcessor->init()) {
397                 debugFatal("Could not initialize receive processor!\n");
398                 return false;
399         }
400         m_receiveProcessor->setVerboseLevel(getDebugLevel());
401
402         // Now we add ports to the processor
403         debugOutput(DEBUG_LEVEL_VERBOSE,"Adding ports to receive processor\n");
404        
405         char *buff;
406         FreebobStreaming::Port *p=NULL;
407
408         // Add audio capture ports
409         if (!addDirPorts(FreebobStreaming::Port::E_Capture, samp_freq, optical_in_mode)) {
410                 return false;
411         }
412
413         // Add MIDI port.  The MOTU only has one MIDI input port, with each
414         // MIDI byte sent using a 3 byte sequence starting at byte 4 of the
415         // event data.
416         asprintf(&buff,"dev%d_cap_MIDI0",m_id);
417         p = new FreebobStreaming::MotuMidiPort(buff,
418                 FreebobStreaming::Port::E_Capture, 4);
419         if (!p) {
420                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n", buff);
421         } else {
422                 if (!m_receiveProcessor->addPort(p)) {
423                         debugWarning("Could not register port with stream processor\n");
424                         free(buff);
425                         return false;
426                 } else {
427                         debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n", buff);
428                 }
429         }
430         free(buff);
431
432         // example of adding an control port:
433 //    asprintf(&buff,"dev%d_cap_%s",m_id,"myportnamehere");
434 //    p=new FreebobStreaming::MotuControlPort(
435 //            buff,
436 //            FreebobStreaming::Port::E_Capture,
437 //            0 // you can add all other port specific stuff you
438 //              // need to pass by extending MotuXXXPort and MotuPortInfo
439 //    );
440 //    free(buff);
441 //
442 //    if (!p) {
443 //        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",buff);
444 //    } else {
445 //
446 //        if (!m_receiveProcessor->addPort(p)) {
447 //            debugWarning("Could not register port with stream processor\n");
448 //            return false;
449 //        } else {
450 //            debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",buff);
451 //        }
452 //    }
453
454         // Do the same for the transmit processor
455         m_transmitProcessor=new FreebobStreaming::MotuTransmitStreamProcessor(
456                 m_1394Service->getPort(), getSamplingFrequency(), event_size_out);
457
458         m_transmitProcessor->setVerboseLevel(getDebugLevel());
459        
460         if(!m_transmitProcessor->init()) {
461                 debugFatal("Could not initialize transmit processor!\n");
462                 return false;
463         }
464
465         // Connect the transmit stream ticks-per-frame hook to the
466         // ticks-per-frame DLL integrator in the receive stream.
467         m_transmitProcessor->setTicksPerFrameDLL(m_receiveProcessor->getTicksPerFrameDLL());
468
469         // Now we add ports to the processor
470         debugOutput(DEBUG_LEVEL_VERBOSE,"Adding ports to transmit processor\n");
471
472         // Add audio playback ports
473         if (!addDirPorts(FreebobStreaming::Port::E_Playback, samp_freq, optical_out_mode)) {
474                 return false;
475         }
476
477         // Add MIDI port.  The MOTU only has one output MIDI port, with each
478         // MIDI byte transmitted using a 3 byte sequence starting at byte 4
479         // of the event data.
480         asprintf(&buff,"dev%d_pbk_MIDI0",m_id);
481         p = new FreebobStreaming::MotuMidiPort(buff,
482                 FreebobStreaming::Port::E_Capture, 4);
483         if (!p) {
484                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n", buff);
485         } else {
486                 if (!m_receiveProcessor->addPort(p)) {
487                         debugWarning("Could not register port with stream processor\n");
488                         free(buff);
489                         return false;
490                 } else {
491                         debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n", buff);
492                 }
493         }
494         free(buff);
495
496         // example of adding an control port:
497 //    asprintf(&buff,"dev%d_pbk_%s",m_id,"myportnamehere");
498 //   
499 //    p=new FreebobStreaming::MotuControlPort(
500 //            buff,
501 //            FreebobStreaming::Port::E_Playback,
502 //            0 // you can add all other port specific stuff you
503 //              // need to pass by extending MotuXXXPort and MotuPortInfo
504 //    );
505 //    free(buff);
506 //
507 //    if (!p) {
508 //        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",buff);
509 //    } else {
510 //        if (!m_transmitProcessor->addPort(p)) {
511 //            debugWarning("Could not register port with stream processor\n");
512 //            return false;
513 //        } else {
514 //            debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",buff);
515 //        }
516 //    }
517        
518         return true;
519 }
520
521 int
522 MotuDevice::getStreamCount() {
523         return 2; // one receive, one transmit
524 }
525
526 FreebobStreaming::StreamProcessor *
527 MotuDevice::getStreamProcessorByIndex(int i) {
528         switch (i) {
529         case 0:
530                 return m_receiveProcessor;
531         case 1:
532                 return m_transmitProcessor;
533         default:
534                 return NULL;
535         }
536         return 0;
537 }
538
539 int
540 MotuDevice::startStreamByIndex(int i) {
541
542 quadlet_t isoctrl = ReadRegister(MOTUFW_REG_ISOCTRL);
543
544         // NOTE: this assumes that you have two streams
545         switch (i) {
546         case 0:
547                 // TODO: do the stuff that is nescessary to make the device
548                 // transmit a stream
549
550                 // Set the streamprocessor channel to the one obtained by
551                 // the connection management
552                 m_receiveProcessor->setChannel(m_iso_recv_channel);
553
554                 // Mask out current transmit settings of the MOTU and replace
555                 // with new ones.  Turn bit 24 on to enable changes to the
556                 // MOTU's iso transmit settings when the iso control register
557                 // is written.  Bit 23 enables iso transmit from the MOTU.
558                 isoctrl &= 0xff00ffff;
559                 isoctrl |= (m_iso_recv_channel << 16);
560                 isoctrl |= 0x00c00000;
561                 WriteRegister(MOTUFW_REG_ISOCTRL, isoctrl);
562                 break;
563         case 1:
564                 // TODO: do the stuff that is nescessary to make the device
565                 // receive a stream
566
567                 // Set the streamprocessor channel to the one obtained by
568                 // the connection management
569                 m_transmitProcessor->setChannel(m_iso_send_channel);
570
571                 // Mask out current receive settings of the MOTU and replace
572                 // with new ones.  Turn bit 31 on to enable changes to the
573                 // MOTU's iso receive settings when the iso control register
574                 // is written.  Bit 30 enables iso receive by the MOTU.
575                 isoctrl &= 0x00ffffff;
576                 isoctrl |= (m_iso_send_channel << 24);
577                 isoctrl |= 0xc0000000;
578                 WriteRegister(MOTUFW_REG_ISOCTRL, isoctrl);
579                 break;
580                
581         default: // Invalid stream index
582                 return -1;
583         }
584
585         return 0;
586 }
587
588 int
589 MotuDevice::stopStreamByIndex(int i) {
590
591 quadlet_t isoctrl = ReadRegister(MOTUFW_REG_ISOCTRL);
592
593         // TODO: connection management: break connection
594         // cfr the start function
595
596         // NOTE: this assumes that you have two streams
597         switch (i) {
598         case 0:
599                 // Turn bit 22 off to disable iso send by the MOTU.  Turn
600                 // bit 23 on to enable changes to the MOTU's iso transmit
601                 // settings when the iso control register is written.
602                 isoctrl &= 0xffbfffff;
603                 isoctrl |= 0x00800000;
604                 WriteRegister(MOTUFW_REG_ISOCTRL, isoctrl);
605                 break;
606         case 1:
607                 // Turn bit 30 off to disable iso receive by the MOTU.  Turn
608                 // bit 31 on to enable changes to the MOTU's iso receive
609                 // settings when the iso control register is written.
610                 isoctrl &= 0xbfffffff;
611                 isoctrl |= 0x80000000;
612                 WriteRegister(MOTUFW_REG_ISOCTRL, isoctrl);
613                 break;
614                
615         default: // Invalid stream index
616                 return -1;
617         }
618
619         return 0;
620 }
621
622 signed int MotuDevice::getIsoRecvChannel(void) {
623         return m_iso_recv_channel;
624 }
625
626 signed int MotuDevice::getIsoSendChannel(void) {
627         return m_iso_send_channel;
628 }
629
630 unsigned int MotuDevice::getOpticalMode(unsigned int dir) {
631         unsigned int reg = ReadRegister(MOTUFW_REG_ROUTE_PORT_CONF);
632
633 debugOutput(DEBUG_LEVEL_VERBOSE, "optical mode: %x %x %x %x\n",dir, reg, reg & MOTUFW_OPTICAL_IN_MODE_MASK,
634 reg & MOTUFW_OPTICAL_OUT_MODE_MASK);
635
636         if (dir == MOTUFW_DIR_IN)
637                 return (reg & MOTUFW_OPTICAL_IN_MODE_MASK) >> 8;
638         else
639                 return (reg & MOTUFW_OPTICAL_OUT_MODE_MASK) >> 10;
640 }
641
642 signed int MotuDevice::setOpticalMode(unsigned int dir, unsigned int mode) {
643         unsigned int reg = ReadRegister(MOTUFW_REG_ROUTE_PORT_CONF);
644         unsigned int opt_ctrl = 0x0000002;
645
646         // Set up the optical control register value according to the current
647         // optical port modes.  At this stage it's not completely understood
648         // what the "Optical control" register does, so the values it's set to
649         // are more or less "magic" numbers.
650         if (reg & MOTUFW_OPTICAL_IN_MODE_MASK != (MOTUFW_OPTICAL_MODE_ADAT<<8))
651                 opt_ctrl |= 0x00000080;
652         if (reg & MOTUFW_OPTICAL_OUT_MODE_MASK != (MOTUFW_OPTICAL_MODE_ADAT<<10))
653                 opt_ctrl |= 0x00000040;
654
655         if (mode & MOTUFW_DIR_IN) {
656                 reg &= ~MOTUFW_OPTICAL_IN_MODE_MASK;
657                 reg |= (mode << 8) & MOTUFW_OPTICAL_IN_MODE_MASK;
658                 if (mode != MOTUFW_OPTICAL_MODE_ADAT)
659                         opt_ctrl |= 0x00000080;
660                 else
661                         opt_ctrl &= ~0x00000080;
662         }
663         if (mode & MOTUFW_DIR_OUT) {
664                 reg &= ~MOTUFW_OPTICAL_OUT_MODE_MASK;
665                 reg |= (mode <<10) & MOTUFW_OPTICAL_OUT_MODE_MASK;
666                 if (mode != MOTUFW_OPTICAL_MODE_ADAT)
667                         opt_ctrl |= 0x00000040;
668                 else
669                         opt_ctrl &= ~0x00000040;
670         }
671
672         // FIXME: there seems to be more to it than this, but for
673         // the moment at least this seems to work.
674         WriteRegister(MOTUFW_REG_ROUTE_PORT_CONF, reg);
675         return WriteRegister(MOTUFW_REG_OPTICAL_CTRL, opt_ctrl);
676 }
677
678 signed int MotuDevice::getEventSize(unsigned int dir) {
679 //
680 // Return the size in bytes of a single event sent to (dir==MOTUFW_OUT) or
681 // from (dir==MOTUFW_IN) the MOTU as part of an iso data packet.
682 //
683 // FIXME: for performance it may turn out best to calculate the event
684 // size in setOpticalMode and cache the result in a data field.  However,
685 // as it stands this will not adapt to dynamic changes in sample rate - we'd
686 // need a setFrameRate() for that.
687 //
688 // At the very least an event consists of the SPH (4 bytes), the control/MIDI
689 // bytes (6 bytes) and 8 analog audio channels (each 3 bytes long).  Note that
690 // all audio channels are sent using 3 bytes.
691 signed int sample_rate = getSamplingFrequency();
692 signed int optical_mode = getOpticalMode(dir);
693 signed int size = 4+6+8*3;
694
695         // 2 channels of AES/EBU is present if a 1x or 2x sample rate is in
696         // use
697         if (sample_rate <= 96000)
698                 size += 2*3;
699
700         // 2 channels of (coax) SPDIF is present for 1x or 2x sample rates so
701         // long as the optical mode is not TOSLINK.  If the optical mode is 
702         // TOSLINK the coax SPDIF channels are replaced by optical TOSLINK   
703         // channels.  Thus between these options we always have an addition 
704         // 2 channels here for 1x or 2x sample rates regardless of the optical
705         // mode.
706         if (sample_rate <= 96000)
707                 size += 2*3;
708
709         // ADAT channels 1-4 are present for 1x or 2x sample rates so long
710         // as the optical mode is ADAT.
711         if (sample_rate<=96000 && optical_mode==MOTUFW_OPTICAL_MODE_ADAT)
712                 size += 4*3;
713
714         // ADAT channels 5-8 are present for 1x sample rates so long as the
715         // optical mode is ADAT.
716         if (sample_rate<=48000 && optical_mode==MOTUFW_OPTICAL_MODE_ADAT)
717                 size += 4*3;
718
719         // When 1x or 2x sample rate is active there are an additional
720         // 2 channels sent in an event.  For capture it is a Mix1 return,
721         // while for playback it is a separate headphone mix.
722         if (sample_rate<=96000)
723                 size += 2*3;
724
725         // Finally round size up to the next quadlet boundary
726         return ((size+3)/4)*4;
727 }
728 /* ======================================================================= */
729
730 bool MotuDevice::addPort(FreebobStreaming::StreamProcessor *s_processor,
731   char *name, enum FreebobStreaming::Port::E_Direction direction,
732   int position, int size) {
733 /*
734  * Internal helper function to add a MOTU port to a given stream processor.
735  * This just saves the unnecessary replication of what is essentially
736  * boilerplate code.  Note that the port name is freed by this function
737  * prior to exit.
738  */
739 FreebobStreaming::Port *p=NULL;
740
741         p = new FreebobStreaming::MotuAudioPort(name, direction, position, size);
742
743         if (!p) {
744                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",name);
745         } else {
746                 if (!s_processor->addPort(p)) {
747                         debugWarning("Could not register port with stream processor\n");
748                         free(name);
749                         return false;
750                 } else {
751                         debugOutput(DEBUG_LEVEL_VERBOSE, "Added port %s\n",name);
752                 }
753                 p->enable();
754         }
755         free(name);
756         return true;
757 }
758 /* ======================================================================= */
759
760 bool MotuDevice::addDirPorts(
761   enum FreebobStreaming::Port::E_Direction direction,
762   unsigned int sample_rate, unsigned int optical_mode) {
763 /*
764  * Internal helper method: adds all required ports for the given direction
765  * based on the indicated sample rate and optical mode.
766  *
767  * Notes: currently ports are not created if they are disabled due to sample
768  * rate or optical mode.  However, it might be better to unconditionally
769  * create all ports and just disable those which are not active.
770  */
771 const char *mode_str = direction==FreebobStreaming::Port::E_Capture?"cap":"pbk";
772 const char *aux_str = direction==FreebobStreaming::Port::E_Capture?"Mix1":"Phones";
773 FreebobStreaming::StreamProcessor *s_processor;
774 unsigned int i, ofs;
775 char *buff;
776
777         if (direction == FreebobStreaming::Port::E_Capture) {
778                 s_processor = m_receiveProcessor;
779         } else {
780                 s_processor = m_transmitProcessor;
781         }
782         // Offset into an event's data of the first audio data
783         ofs = 10;
784
785         // Add ports for the Mix1 return / Phones send which is present for
786         // 1x and 2x sampling rates.
787         if (sample_rate<=96000) {
788                 for (i=0; i<2; i++, ofs+=3) {
789                         asprintf(&buff,"dev%d_%s_%s-%c", m_id, mode_str,
790                           aux_str, i==0?'L':'R');
791                         if (!addPort(s_processor, buff, direction, ofs, 0))
792                                 return false;
793                 }
794         }
795
796         // Unconditionally add the 8 analog capture ports since they are
797         // always present no matter what the device configuration is.
798         for (i=0; i<8; i++, ofs+=3) {
799                 asprintf(&buff,"dev%d_%s_Analog%d", m_id, mode_str, i+1);
800                 if (!addPort(s_processor, buff, direction, ofs, 0))
801                         return false;
802         }
803
804         // AES/EBU ports are present for 1x and 2x sampling rates on the
805         // Traveler.  On earlier interfaces (for example, 828 MkII) this
806         // space was taken up with a separate "main out" send.
807         // FIXME: what is in this position of incoming data on an 828 MkII?
808         if (sample_rate <= 96000) {
809                 for (i=0; i<2; i++, ofs+=3) {
810                         if (m_motu_model == MOTUFW_MODEL_TRAVELER) {
811                                 asprintf(&buff,"dev%d_%s_AES/EBU%d", m_id, mode_str, i+1);
812                         } else {
813                                 if (direction == FreebobStreaming::Port::E_Capture)
814                                         asprintf(&buff,"dev%d_%s_Mic%d", m_id, mode_str, i+1);
815                                 else
816                                         asprintf(&buff,"dev%d_%s_MainOut-%c", m_id, mode_str, i==0?'L':'R');
817                         }
818                         if (!addPort(s_processor, buff, direction, ofs, 0))
819                                 return false;
820                 }
821         }
822
823         // SPDIF ports are present for 1x and 2x sampling rates so long
824         // as the optical mode is not TOSLINK.
825         if (sample_rate<=96000 && optical_mode!=MOTUFW_OPTICAL_MODE_TOSLINK) {
826                 for (i=0; i<2; i++, ofs+=3) {
827                         asprintf(&buff,"dev%d_%s_SPDIF%d", m_id, mode_str, i+1);
828                         if (!addPort(s_processor, buff, direction, ofs, 0))
829                                 return false;
830                 }
831         }
832
833         // TOSLINK ports are present for 1x and 2x sampling rates so long
834         // as the optical mode is set to TOSLINK.
835         if (sample_rate<=96000 && optical_mode==MOTUFW_OPTICAL_MODE_TOSLINK) {
836                 for (i=0; i<2; i++, ofs+=3) {
837                         asprintf(&buff,"dev%d_%s_TOSLINK%d", m_id, mode_str, i+1);
838                         if (!addPort(s_processor, buff, direction, ofs, 0))
839                                 return false;
840                 }
841         }
842
843         // ADAT ports 1-4 are present for 1x and 2x sampling rates so long
844         // as the optical mode is set to ADAT.
845         if (sample_rate<=96000 && optical_mode==MOTUFW_OPTICAL_MODE_ADAT) {
846                 for (i=0; i<4; i++, ofs+=3) {
847                         asprintf(&buff,"dev%d_%s_ADAT%d", m_id, mode_str, i+1);
848                         if (!addPort(s_processor, buff, direction, ofs, 0))
849                                 return false;
850                 }
851         }
852
853         // ADAT ports 5-8 are present for 1x sampling rates so long as the
854         // optical mode is set to ADAT.
855         if (sample_rate<=48000 && optical_mode==MOTUFW_OPTICAL_MODE_ADAT) {
856                 for (i=4; i<8; i++, ofs+=3) {
857                         asprintf(&buff,"dev%d_%s_ADAT%d", m_id, mode_str, i+1);
858                         if (!addPort(s_processor, buff, direction, ofs, 0))
859                                 return false;
860                 }
861         }
862
863         return true;
864 }
865 /* ======================================================================== */
866
867 unsigned int MotuDevice::ReadRegister(unsigned int reg) {
868 /*
869  * Attempts to read the requested register from the MOTU.
870  */
871
872 quadlet_t quadlet;
873 assert(m_1394Service);
874        
875   quadlet = 0;
876   // Note: 1394Service::read() expects a physical ID, not the node id
877   if (m_1394Service->read(0xffc0 | m_nodeId, MOTUFW_BASE_ADDR+reg, 4, &quadlet) < 0) {
878     debugError("Error doing motu read from register 0x%06x\n",reg);
879   }
880
881   return ntohl(quadlet);
882 }
883
884 signed int MotuDevice::WriteRegister(unsigned int reg, quadlet_t data) {
885 /*
886  * Attempts to write the given data to the requested MOTU register.
887  */
888
889   unsigned int err = 0;
890   data = htonl(data);
891
892   // Note: 1394Service::write() expects a physical ID, not the node id
893   if (m_1394Service->write(0xffc0 | m_nodeId, MOTUFW_BASE_ADDR+reg, 4, &data) < 0) {
894     err = 1;
895     debugError("Error doing motu write to register 0x%06x\n",reg);
896   }
897
898   usleep(100);
899   return (err==0)?0:-1;
900 }
901
902 }
Note: See TracBrowser for help on using the browser.