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

Revision 428, 27.3 kB (checked in by jwoithe, 17 years ago)

MOTU: more work trying to get MOTU working with the new streaming framework.

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