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

Revision 415, 27.4 kB (checked in by pieterpalmers, 16 years ago)

ieee1394service:
- implemented 64bit compare-swap-lock operation (needed for DICE)
- small name change of (un)registerARMhandler to (un)registerARMHandler

iavdevice.h:
- made the stream start/stop functions return bool instead of int
- updated function documentation for consistency and to reflect changes

BeBoB avdevice:
- replaced the 2 fixed streamprocessor pointers with a 2 vectors of streamprocessors
- implemented the 'snoop mode' (cannot be activated yet)

libstreaming:
- removed unused 'type' attribute from AmdtpPortInfo? & children

mh_avdevice, motu_avdevice, rme_avdevice:
- replaced m_1394service with m_p1394service for consistence

maudio_avdevice.cpp:
- removed unused code

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