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

Revision 445, 10.6 kB (checked in by pieterpalmers, 15 years ago)

* name change from FreeBoB to FFADO
* replaced tabs by 4 spaces
* got rid of end-of-line spaces
* made all license and copyrights conform

library becomes LGPL, apps become GPL
explicitly state LGPL v2.1 and GPL v2 (don't like v3 draft)

copyrights are 2005-2007 Daniel & Pieter
except for the MotU stuff (C) Jonathan, Pieter

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
274 protected:
275     std::string m_Name; ///< Port name, [at construction]
276
277     enum E_SignalType m_SignalType; ///< Signalling type, [at construction]
278     enum E_BufferType m_BufferType; ///< Buffer type, [at construction]
279
280     bool m_disabled; ///< is the port disabled?, [anytime]
281     bool m_initialized; ///< is the port initialized? [after init()]
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 };
310
311 /*!
312 \brief The Base Class for an Audio Port
313
314
315 */
316 class AudioPort : public Port {
317
318 public:
319
320     AudioPort(std::string name, enum E_Direction direction)
321       : Port(name, E_Audio, direction)
322     {};
323
324     virtual ~AudioPort() {};
325
326 protected:
327
328
329 };
330
331 /*!
332 \brief The Base Class for a Midi Port
333
334
335 */
336 class MidiPort : public Port {
337
338 public:
339
340     MidiPort(std::string name, enum E_Direction direction)
341       : Port(name, E_Midi, direction)
342     {};
343     virtual ~MidiPort() {};
344
345
346 protected:
347
348
349 };
350
351 /*!
352 \brief The Base Class for a control port
353
354
355 */
356 class ControlPort : public Port {
357
358 public:
359
360     ControlPort(std::string name, enum E_Direction direction)
361       : Port(name, E_Control, direction)
362     {};
363     virtual ~ControlPort() {};
364
365
366 protected:
367
368
369 };
370
371 }
372
373 #endif /* __FFADO_PORT__ */
374
375
Note: See TracBrowser for help on using the browser.