root/trunk/libffado/src/motu/motu_avdevice.cpp

Revision 554, 29.8 kB (checked in by ppalmers, 17 years ago)

Merge echoaudio branch into trunk.

This adds support for the Echo Audiofire devices to FFADO. Possibly also other devices working with the Apple Class Driver will work with this code. It is not fully complete yet, but the main rework is
done.

First of all the IAvDevice class/interface is renamed to FFADODevice, in order to separate the AV/C code from the FFADO API code. A device supported by FFADO implements a FFADODevice.

The BeBoB device has been split up into three groups:
- libavc/* : all code and commands that are specified by AV/C specs. Note that a lot of the code that used to be in BeBoB::AvDevice? now resides in AVC::Unit
- genericavc/* : a FFADODevice that uses AV/C descriptors & commands for discovery and config
- bebob/* : the bebob FFADODevice that inherits from GenericAVC::AvDevice? but that uses BridgeCo? commands for discovery

Everything has been moved as high as possible in the class hierarchy. If necessary, a subclass that uses device specific commands is introduced (e.g. BeBoB::Plug inherits from AVC::Plug and uses the
BridgeCo? extended plug info command to discover it's properties).

There are some other fixes along the way that have been done too.

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