root/trunk/libffado/src/libstreaming/Port.h

Revision 554, 10.8 kB (checked in by ppalmers, 17 years ago)

Merge echoaudio branch into trunk.

This adds support for the Echo Audiofire devices to FFADO. Possibly also other devices working with the Apple Class Driver will work with this code. It is not fully complete yet, but the main rework is
done.

First of all the IAvDevice class/interface is renamed to FFADODevice, in order to separate the AV/C code from the FFADO API code. A device supported by FFADO implements a FFADODevice.

The BeBoB device has been split up into three groups:
- libavc/* : all code and commands that are specified by AV/C specs. Note that a lot of the code that used to be in BeBoB::AvDevice? now resides in AVC::Unit
- genericavc/* : a FFADODevice that uses AV/C descriptors & commands for discovery and config
- bebob/* : the bebob FFADODevice that inherits from GenericAVC::AvDevice? but that uses BridgeCo? commands for discovery

Everything has been moved as high as possible in the class hierarchy. If necessary, a subclass that uses device specific commands is introduced (e.g. BeBoB::Plug inherits from AVC::Plug and uses the
BridgeCo? extended plug info command to discover it's properties).

There are some other fixes along the way that have been done too.

Line 
1 /*
2  * Copyright (C) 2005-2007 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License version 2.1, as published by the Free Software Foundation;
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21  * MA 02110-1301 USA
22  */
23
24 #ifndef __FFADO_PORT__
25 #define __FFADO_PORT__
26
27 #include <stdint.h>
28
29 #include "../debugmodule/debugmodule.h"
30 #include <string>
31 #include "libutil/ringbuffer.h"
32
33 namespace Streaming {
34
35 /*!
36 \brief The Base Class for Ports
37
38  Ports are the entities that provide the interface between the ISO streaming
39  layer and the datatype-specific layer. You can define port types by subclassing
40  the base port class.
41
42  After creating a port, you have to set its parameters and then call the init() function.
43  This is because a port needs information from two sources to operate:
44  1) the stream composition information from the AvDevice
45  2) the streaming API setup (buffer type, data type, ...)
46
47  \note There are not much virtual functions here because of the high frequency of
48        calling. We try to do everything with a base class getter, and a child class
49        setter. If this isn't possible, we do a static_cast. This however can only be
50        done inside the streamprocessor that handles the specific sub-class types of
51        the ports. i.e. by design you should make sure that the static_cast will be
52        OK.
53
54  \todo rework the implementation into something more beautifull
55 */
56 class Port {
57
58 public:
59     friend class PortManager;
60
61     /*
62      * IMPORTANT: if you add something to any of these enum's, be sure to
63      *            check the code where they are used.
64      */
65
66     /*!
67     \brief Specifies the buffer type for ports
68
69     A PointerBuffer uses the getBufferAddress() and setBufferAddres() interface
70     A Ringbuffer uses the read/write interface
71     */
72     enum E_BufferType {
73         E_PointerBuffer,
74         E_RingBuffer
75     };
76
77     /*!
78     \brief Specifies the signalling type for ports
79     */
80     enum E_SignalType {
81         E_PacketSignalled, ///< the port is to be processed for every packet
82         E_PeriodSignalled, ///< the port is to be processed after a period of frames
83 //         E_SampleSignalled ///< the port is to be processed after each frame (sample)
84     };
85
86     /*!
87     \brief The datatype of the port buffer
88     */
89     enum E_DataType {
90         E_Float,
91         E_Int24,
92         E_MidiEvent,
93         E_Default,
94     };
95
96     /*!
97     \brief The port type
98     */
99     enum E_PortType {
100         E_Audio,
101         E_Midi,
102         E_Control,
103     };
104
105     /*!
106     \brief The port direction
107     */
108     enum E_Direction {
109         E_Playback,
110         E_Capture,
111     };
112
113     Port(std::string name, enum E_PortType porttype, enum E_Direction direction);
114
115     virtual ~Port()
116       {};
117
118
119     /// Enable the port. (this can be called anytime)
120     void enable();
121     /// Disable the port. (this can be called anytime)
122     void disable();
123     /// is the port disabled? (this can be called anytime)
124     bool isDisabled() {return m_disabled;};
125
126     /*!
127     \brief Initialize the port
128     */
129     bool init();
130
131     bool prepare() {return true;};
132     bool reset();
133
134     std::string getName() {return m_Name;};
135     bool setName(std::string name);
136
137     /**
138      * \brief returns the size of the events in the port buffer, in bytes
139      *
140      */
141     unsigned int getEventSize();
142
143     /**
144      * \brief sets the event type for the port buffer
145      *
146      * \note use before calling init()
147      */
148     virtual bool setDataType(enum E_DataType);
149
150     enum E_DataType getDataType() {return m_DataType;};
151
152     /**
153      * \brief sets the event type for the port buffer
154      *
155      * \note use before calling init()
156      */
157     virtual bool setSignalType(enum E_SignalType );
158
159     enum E_SignalType getSignalType() {return m_SignalType;}; ///< returns the signalling type of the port
160
161     /**
162      * \brief sets the buffer type for the port
163      *
164      * \note use before calling init()
165      */
166     virtual bool setBufferType(enum E_BufferType );
167
168     enum E_BufferType getBufferType() {return m_BufferType;}; ///< returns the buffer type of the port
169
170     enum E_PortType getPortType() {return m_PortType;}; ///< returns the port type (is fixed)
171     enum E_Direction getDirection() {return m_Direction;}; ///< returns the direction (is fixed)
172
173     /**
174      * \brief returns the size of the port buffer
175      *
176      * counted in number of E_DataType units (events), not in bytes
177      *
178      */
179     unsigned int getBufferSize() {return m_buffersize;};
180
181     /**
182      * \brief sets the size of the port buffer
183      *
184      * counted in number of E_DataType units, not in bytes
185      *
186      * if there is an external buffer assigned, it should
187      * be large enough
188      * if there is an internal buffer, it will be resized
189      *
190      * \note use before calling init()
191      */
192     virtual bool setBufferSize(unsigned int);
193
194     /**
195      * \brief use an external buffer (or not)
196      *
197      * \note use before calling init()
198      */
199     virtual bool useExternalBuffer(bool b);
200
201     void setExternalBufferAddress(void *buff);
202
203
204     /**
205      * \brief enable/disable ratecontrol
206      *
207      * Rate control is nescessary for some types of ports (most notably
208      * midi). The StreamProcessor that handles the port should call canRead()
209      * everytime a 'slot' that could be filled with an event passes. The canRead
210      * function will return true if
211      *  (1) there is an event ready in the buffer
212      *  (2) we are allowed to send an event in this slot
213      *
214      * Setting the rate works is done with the slot_interval and the event_interval
215      * parameters. On every call to canRead(), a counter is decremented with
216      * slot_interval. If the counter drops below 0, canRead() returns true and resets
217      * the counter to event_interval.
218      *
219      * e.g. for AMDTP midi, we are only allowed to send a midi byte every 320us
220      *      if the SYT interval is 8, there is exactly one midi slot every packet.
221      *    therefore the slot_interval is 1/8000s (=125us), and the event_interval
222      *      is 320us.
223      *
224      *      Note that the interval parameters are unitless, so you can adapt them
225      *      to your needs. In the AMDTP case for example, when the SYT interval is 32
226      *      (when the samplerate is 192kHz for example) there are 4 midi slots in
227      *      each packet, making the slot time interval 125us/4 = 31.25us.
228      *      The event time interval stays the same (320us). We can however set the
229      *    slot_interval to 3125 and the event_interval to 32000, as we can choose
230      *    the unit of the counter time step (chosen to be 10ns in this case).
231      *
232      * The average argument deserves some attention too. If average is true, we use
233      * average rate control. This means that on average there will be a delay of
234      * event_interval between two events, but that sometimes there can be a smaller
235      * delay. This mode fixes the average rate of the stream.
236      * If average is false, there will always be a minimal delay of event_interval
237      * between two events. This means that the maximum rate of the stream is fixed,
238      * and that the average rate will be lower than (or at max equal to) the rate in
239      * average mode.
240      *
241      *
242      * \note only works for the E_RingBuffer ports
243      * \note use before calling init()
244      *
245      * @param use set this to true to use rate control
246      * @param slot_interval the interval between slots
247      * @param event_interval the interval between events
248      * @param average use average rate control
249      * @return true if rate control was enabled/disabled successfully
250      */
251     virtual bool useRateControl(bool use, unsigned int slot_interval,
252                                 unsigned int event_interval, bool average);
253
254     bool usingRateControl() { return m_do_ratecontrol;}; ///< are we using rate control?
255
256     /**
257      * Can we send an event in this slot. subject to rate control and
258      * byte availability.
259      * @return true if we can send an event on this slot
260      */
261     bool canRead();
262
263     // FIXME: this is not really OO, but for performance???
264     void *getBufferAddress();
265
266     // TODO: extend this with a blocking interface
267     bool writeEvent(void *event); ///< write one event
268     bool readEvent(void *event); ///< read one event
269     int writeEvents(void *event, unsigned int nevents); ///< write multiple events
270     int readEvents(void *event, unsigned int nevents); ///< read multiple events
271
272     virtual void setVerboseLevel(int l);
273     virtual void show();
274    
275 protected:
276     std::string m_Name; ///< Port name, [at construction]
277
278     enum E_SignalType m_SignalType; ///< Signalling type, [at construction]
279     enum E_BufferType m_BufferType; ///< Buffer type, [at construction]
280
281     bool m_disabled; ///< is the port disabled?, [anytime]
282
283     unsigned int m_buffersize;
284     unsigned int m_eventsize;
285
286     enum E_DataType m_DataType;
287     enum E_PortType m_PortType;
288     enum E_Direction m_Direction;
289
290     void *m_buffer;
291     ffado_ringbuffer_t *m_ringbuffer;
292     bool m_use_external_buffer;
293
294     bool m_do_ratecontrol;
295     int m_event_interval;
296     int m_slot_interval;
297     int m_rate_counter;
298     int m_rate_counter_minimum;
299     bool m_average_ratecontrol;
300
301     bool allocateInternalBuffer();
302     void freeInternalBuffer();
303
304     bool allocateInternalRingBuffer();
305     void freeInternalRingBuffer();
306
307     DECLARE_DEBUG_MODULE;
308    
309     // the state machine
310     protected:
311         enum EStates {
312             E_Created,
313             E_Initialized,
314             E_Prepared,
315             E_Running,
316             E_Error
317         };
318
319         enum EStates m_State;
320 };
321
322 /*!
323 \brief The Base Class for an Audio Port
324
325
326 */
327 class AudioPort : public Port {
328
329 public:
330
331     AudioPort(std::string name, enum E_Direction direction)
332       : Port(name, E_Audio, direction)
333     {};
334
335     virtual ~AudioPort() {};
336
337 protected:
338
339
340 };
341
342 /*!
343 \brief The Base Class for a Midi Port
344
345
346 */
347 class MidiPort : public Port {
348
349 public:
350
351     MidiPort(std::string name, enum E_Direction direction)
352       : Port(name, E_Midi, direction)
353     {};
354     virtual ~MidiPort() {};
355
356
357 protected:
358
359
360 };
361
362 /*!
363 \brief The Base Class for a control port
364
365
366 */
367 class ControlPort : public Port {
368
369 public:
370
371     ControlPort(std::string name, enum E_Direction direction)
372       : Port(name, E_Control, direction)
373     {};
374     virtual ~ControlPort() {};
375
376
377 protected:
378
379
380 };
381
382 }
383
384 #endif /* __FFADO_PORT__ */
385
386
Note: See TracBrowser for help on using the browser.