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

Revision 657, 32.1 kB (checked in by jwoithe, 15 years ago)

Make bandwidth allocation dependent on actual device configuration (and therefore the number of channels actually active).

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