root/branches/ppalmers-streaming/src/ffadodevice.h

Revision 674, 13.4 kB (checked in by ppalmers, 16 years ago)

Introduce bus reset handling

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