root/trunk/libffado/src/ffadodevice.h

Revision 750, 13.6 kB (checked in by ppalmers, 15 years ago)

Code refactoring. Tries to simplify things and tries to put all code where it belongs.

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