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

Revision 402, 28.9 kB (checked in by pieterpalmers, 16 years ago)

adapted the Motu SP to the new stream sync framework

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