root/branches/streaming-rework/src/motu/motu_avdevice.cpp

Revision 426, 27.3 kB (checked in by pieterpalmers, 17 years ago)

- changed the IAvDevice from an interface to a base class,

since there is some code duplication starting to
appear.

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