root/branches/libffado-2.0/src/ffadodevice.h

Revision 1385, 15.3 kB (checked in by ppalmers, 12 years ago)

Implement a mechanism to disable the samplerate and clock source controls while the device is streaming in order to avoid changes that could mess up jack. The saffire pro controls that cause a device reset to
happen are also disabled while streaming is active.

Line 
1 /*
2  * Copyright (C) 2005-2008 by Daniel Wagner
3  * Copyright (C) 2005-2008 by Pieter Palmers
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 program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 2 of the License, or
13  * (at your option) version 3 of the License.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #ifndef FFADODEVICE_H
26 #define FFADODEVICE_H
27
28 #include "libutil/OptionContainer.h"
29 #include "libutil/PosixMutex.h"
30
31 #include "libcontrol/BasicElements.h"
32
33 #include "libieee1394/vendor_model_ids.h"
34
35 #include <vector>
36 #include <string>
37
38 class DeviceManager;
39 class ConfigRom;
40 class Ieee1394Service;
41
42 namespace Streaming {
43     class StreamProcessor;
44 }
45
46 namespace Control {
47     class Container;
48 }
49
50 /*!
51 @brief Base class for device support
52
53  This class should be subclassed to implement ffado support
54  for a specific device.
55
56 */
57 class FFADODevice
58     : public Util::OptionContainer,
59       public Control::Container
60 {
61 public:
62     FFADODevice( DeviceManager&, std::auto_ptr< ConfigRom >( configRom ) );
63
64     virtual ~FFADODevice();
65
66     /**
67      * @brief Compares the GUID of two FFADODevices
68      *
69      * This function compares the GUID of two FFADODevices and returns true
70      * if the GUID of @ref a is larger than the GUID of @ref b . This is intended
71      * to be used with the STL sort() algorithm.
72      *
73      * Note that GUID's are converted to integers for this.
74      *
75      * @param a pointer to first FFADODevice
76      * @param b pointer to second FFADODevice
77      *
78      * @returns true if the GUID of @ref a is larger than the GUID of @ref b .
79      */
80     static bool compareGUID( FFADODevice *a, FFADODevice *b );
81
82     /// Returns the 1394 service of the FFADO device
83     virtual Ieee1394Service& get1394Service();
84     /// Returns the ConfigRom object of the device node.
85     virtual ConfigRom& getConfigRom() const;
86
87     /**
88      * @brief Called by DeviceManager to load device model from cache.
89      *
90      * This function is called before discover in order to speed up
91      * system initializing.
92      *
93      * @returns true if device was cached and successfully loaded from cache
94      */
95     virtual bool loadFromCache();
96
97     /**
98      * @brief Called by DeviceManager to allow device driver to save a cache version
99      * of the current configuration.
100      *
101      * @returns true if caching was successful. False doesn't mean an error just,
102      * the driver was unable to store the configuration
103      */
104     virtual bool saveCache();
105
106     /**
107      * @brief Called by DeviceManager to check whether a device requires rediscovery
108      *
109      * This function is called to figure out if the device has to be rediscovered
110      * e.g. after a bus reset where the device internal structure changed.
111      *
112      * @returns true if device requires rediscovery
113      */
114     virtual bool needsRediscovery();
115
116     /**
117      * @brief This is called by the DeviceManager to create an instance of the device
118      *
119      * This function enables the FFADODevice to return a subclass of itself should that
120      * be needed. If we don't do this we'd need to know about the subclasses in the
121      * devicemanager, whilst now we don't.
122      *
123      * The function should return an instance of either the class itself or a subclass
124      * of itself.
125      *
126      * This should be overridden in any subclass.
127      *
128      * @return a new instance of the AvDevice type, NULL when unsuccessful
129      */
130     static FFADODevice * createDevice( std::auto_ptr<ConfigRom>( x ));
131
132     /**
133      * @brief This is called by the DeviceManager to discover & configure the device
134      *
135      * @return true if the device was discovered successfuly
136      */
137     virtual bool discover() = 0;
138
139     /**
140      * @brief Set the samping frequency
141      * @param samplingFrequency
142      * @return true if successful
143      */
144     virtual bool setSamplingFrequency( int samplingFrequency ) = 0;
145     /**
146      * @brief get the samplingfrequency as an integer
147      * @return the sampling frequency as integer
148      */
149     virtual int getSamplingFrequency( ) = 0;
150
151     /**
152      * @brief get the supported sampling frequencies
153      * @return a vector containing the supported sampling frequencies
154      */
155     virtual std::vector<int> getSupportedSamplingFrequencies( ) = 0;
156
157     /**
158      * @brief sync state enum
159      */
160     enum eSyncState {
161         eSS_Unknown=0,
162         eSS_Locked=1,
163         eSS_Unlocked=2,
164     };
165
166     /**
167      * @brief gets the devices current synchronization state
168      * @return the device's sync state
169      */
170     virtual enum eSyncState getSyncState( );
171
172     /**
173      * @brief clock source types
174      */
175     enum eClockSourceType {
176         eCT_Invalid,   ///> invalid entry (e.g. on error)
177         eCT_Auto,      ///> automatically select clock source
178         eCT_Internal,  ///> internal sync (unspecified)
179         eCT_1394Bus,   ///> Sync on the 1394 bus clock (e.g. CSP)
180         eCT_SytMatch,  ///> SYT match on incoming audio stream
181         eCT_SytStream, ///> SYT match on incoming sync stream
182         eCT_WordClock, ///> SYT on WordClock input
183         eCT_SPDIF,     ///> SYT on SPDIF input
184         eCT_ADAT,      ///> SYT on ADAT input
185         eCT_TDIF,      ///> SYT on TDIF input
186         eCT_AES,       ///> SYT on AES input
187         eCT_SMPTE,     ///> SMPTE clock
188     };
189
190     /**
191      * @brief convert the clock source type to a C string
192      * @return a C string describing the clock source type
193      */
194     static const char *ClockSourceTypeToString(enum eClockSourceType);
195
196     /**
197      * @brief Clock source identification struct
198      */
199     class ClockSource {
200         public:
201         ClockSource()
202             : type( eCT_Invalid )
203             , id( 0 )
204             , valid( false )
205             , active( false )
206             , locked( true )
207             , slipping( false )
208             , description( "" )
209         {};
210         /// indicates the type of the clock source (e.g. eCT_ADAT)
211         enum eClockSourceType type;
212         /// indicated the id of the clock source (e.g. id=1 => clocksource is ADAT_1)
213         unsigned int id;
214         /// is the clock source valid (i.e. can be selected) at this moment?
215         bool valid;
216         /// is the clock source active at this moment?
217         bool active;
218         /// is the clock source locked?
219         bool locked;
220         /// is the clock source slipping?
221         bool slipping;
222         /// description of the clock struct (optional)
223         std::string description;
224        
225         bool operator==(const ClockSource& x) {
226             return (type == x.type) && (id == x.id);
227         }
228     };
229
230     typedef std::vector< ClockSource > ClockSourceVector;
231     typedef std::vector< ClockSource >::iterator ClockSourceVectorIterator;
232
233     /**
234      * @brief Get the clocksources supported by this device
235      *
236      * This function returns a vector of ClockSource structures that contains
237      * one entry for every clock source supported by the device.
238      *
239      * @returns a vector of ClockSource structures
240      */
241     virtual ClockSourceVector getSupportedClockSources() = 0;
242
243
244     /**
245      * @brief Sets the active clock source of this device
246      *
247      * This function sets the clock source of the device.
248      *
249      * @returns true upon success. false upon failure.
250      */
251     virtual bool setActiveClockSource(ClockSource) = 0;
252
253     /**
254      * @brief Returns the active clock source of this device
255      *
256      * This function returns the active clock source of the device.
257      *
258      * @returns the active ClockSource
259      */
260     virtual ClockSource getActiveClockSource() = 0;
261
262     /**
263      * @brief stream states
264      */
265     enum eStreamingState {
266         eSS_Idle,        ///> not streaming
267         eSS_Sending,     ///> the device is sending a stream
268         eSS_Receiving,   ///> the device is receiving a stream
269         eSS_Both,        ///> the device is sending and receiving a stream
270     };
271
272     /**
273      * @brief gets the devices current synchronization state
274      * @return the device's sync state
275      */
276     virtual enum eStreamingState getStreamingState();
277
278     /**
279      * @brief This is called by the device manager to give the device a unique ID.
280      *
281      * The purpose of this is to allow for unique port naming
282      * in case there are multiple identical devices on the bus.
283      * Some audio API's (e.g. jack) don't work properly when the
284      * port names are not unique.
285      *
286      * Say you have two devices having a port named OutputLeft.
287      * This can cause the streaming
288      * part to present two OutputLeft ports to the audio API,
289      * which won't work. This ID will allow you to construct
290      * the port names as 'dev1_OutputLeft' and 'dev2_OutputLeft'
291      *
292      * @note Currently this is a simple integer that is equal to
293      *       the position of the device in the devicemanager's
294      *       device list. Therefore it is dependant on the order
295      *       in which the devices are detected. The side-effect
296      *       of this is that it is dependant on the bus topology
297      *       and history (e.g. busresets etc). This makes that
298      *       these ID's are not fixed to a specific physical device.
299      *       At some point, we will replaced this with a GUID based
300      *       approach, which is tied to a physical device and is
301      *       bus & time independant.
302      *
303      * @param id
304      * @return true if successful
305      */
306     bool setId(unsigned int id);
307
308     /**
309      * @brief Outputs the device configuration to stderr/stdout [debug helper]
310      *
311      * This function prints out a (detailed) description of the
312      * device detected, and its configuration.
313      */
314     virtual void showDevice();
315
316     /**
317      * @brief Lock the device
318      *
319      * This is called by the streaming layer before we start manipulating
320      * and/or using the device.
321      *
322      * It should implement the mechanisms provided by the device to
323      * make sure that no other controller claims control of the device.
324      *
325      * @return true if successful, false if not
326      */
327     virtual bool lock() = 0;
328
329     /**
330      * @brief Unlock the device
331      *
332      * This is called by the streaming layer after we finish manipulating
333      * and/or using the device.
334      *
335      * It should implement the mechanisms provided by the device to
336      * give up exclusive control of the device.
337      *
338      * @return true if successful, false if not
339      */
340     virtual bool unlock() = 0;
341
342     /**
343      * @brief Enable streaming on all 'started' streams
344      *
345      * Enables the ISO streaming on all streams that are 'started'
346      * using startStreamByIndex. This is useful to control a 'master enable'
347      * function on the device.
348      *
349      * @return true if successful
350      */
351     virtual bool enableStreaming();
352
353     /**
354      * @brief Disable streaming on all streams
355      *
356      * Disables ISO streaming on all streams.
357      * This is useful to control a 'master enable'
358      * function on the device.
359      *
360      * @return true if successful
361      */
362     virtual bool disableStreaming();
363
364     /**
365      * @brief Prepare the device
366      *
367      * This is called by the streaming layer after the configuration
368      * parameters (e.g. sample rate) are set, and before
369      * getStreamProcessor[*] functions are called.
370      *
371      * It should be used to prepare the device's streamprocessors
372      * based upon the device's current configuration. Normally
373      * the streaming layer will not change the device's configuration
374      * after calling this function.
375      *
376      * @return true if successful, false if not
377      */
378     virtual bool prepare() = 0;
379
380     /**
381      * @brief Returns the number of ISO streams implemented/used by this device
382      *
383      * Most likely this is 2 streams, i.e. one transmit stream and one
384      * receive stream. However there are devices that implement more, for
385      * example BeBoB's implement 4 streams:
386      * - 2 audio streams (1 xmit/1 recv)
387      * - 2 sync streams (1 xmit/1 recv), which are an optional sync source
388      *   for the device.
389      *
390      * @note you have to have a StreamProcessor for every stream. I.e.
391      *       getStreamProcessorByIndex(i) should return a valid StreamProcessor
392      *       for i=0 to i=getStreamCount()-1
393      *
394      * @return number of streams available (both transmit and receive)
395      */
396     virtual int getStreamCount() = 0;
397
398     /**
399      * @brief Returns the StreamProcessor object for the stream with index i
400      *
401      * @note a streamprocessor returned by getStreamProcessorByIndex(i)
402      *       cannot be the same object as one returned by
403      *       getStreamProcessorByIndex(j) if i isn't equal to j
404      * @note you cannot have two streamprocessors handling the same ISO
405      *       channel (on the same port)
406      *
407      * @param i : Stream index
408      * @pre @ref i smaller than getStreamCount()
409      * @return a StreamProcessor object if successful, NULL otherwise
410      */
411     virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i) = 0;
412
413     /**
414      * @brief starts the stream with index i
415      *
416      * This function is called by the streaming layer when this stream should
417      * be started, i.e. the device should start sending data or should be prepared to
418      * be ready to receive data.
419      *
420      * It returns the channel number that was assigned for this stream.
421      * Channel allocation should be done using the allocation functions provided by the
422      * Ieee1394Service object that is passed in the constructor.
423      *
424      * @param i : Stream index
425      * @pre @ref i smaller than getStreamCount()
426      * @return true if successful, false if not
427      */
428     virtual bool startStreamByIndex(int i) = 0;
429
430     /**
431      * @brief stops the stream with index @ref i
432      *
433      * @param i : Stream index
434      * @pre @ref i smaller than getStreamCount()
435      * @return true if successful, false if not
436      */
437     virtual bool stopStreamByIndex(int i) = 0;
438
439     /**
440      * set verbosity level
441      */
442     virtual void setVerboseLevel(int l);
443
444     /**
445      * @brief return the node id of this device
446      *
447      * @return the node id
448      */
449     int getNodeId();
450
451     /**
452      * @brief return the nick name of this device
453      *
454      * @return string containing the name
455      */
456     virtual std::string getNickname();
457
458     /**
459      * @brief set the nick name of this device
460      * @param name new nickname
461      * @return true if successful
462      */
463     virtual bool setNickname(std::string name);
464
465     /**
466      * @brief handle a bus reset
467      *
468      * Called whenever a bus reset is detected. Handle everything
469      * that has to be done to cope with a bus reset.
470      *
471      */
472     // FIXME: not virtual?
473     void handleBusReset();
474
475     // the Control::Container functions
476     virtual std::string getName();
477     virtual bool setName( std::string n )
478         { return false; };
479
480     DeviceManager& getDeviceManager()
481         {return m_pDeviceManager;};
482 private:
483     std::auto_ptr<ConfigRom>( m_pConfigRom );
484     DeviceManager& m_pDeviceManager;
485     Control::Container* m_genericContainer;
486 protected:
487     DECLARE_DEBUG_MODULE;
488     Util::PosixMutex m_DeviceMutex;
489 };
490
491 #endif
Note: See TracBrowser for help on using the browser.