root/branches/streaming-rework/src/libstreaming/Port.h

Revision 386, 10.1 kB (checked in by pieterpalmers, 16 years ago)

- moved files around to the place they belong
- fixed all compile warnings

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