root/branches/ppalmers-streaming/src/libstreaming/generic/Port.h

Revision 705, 10.8 kB (checked in by ppalmers, 16 years ago)

restructure the streaming directory

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