root/trunk/libffado/src/libutil/TimestampedBuffer.h

Revision 445, 6.4 kB (checked in by pieterpalmers, 14 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 /* $Id$ */
2
3 /*
4  *   FFADO Streaming API
5  *   FFADO = Firewire (pro-)audio for linux
6  *
7  *   http://ffado.sf.net
8  *
9  *   Copyright (C) 2005,2006,2007 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 __FFADO_TIMESTAMPEDBUFFER__
29 #define __FFADO_TIMESTAMPEDBUFFER__
30
31 #include "../debugmodule/debugmodule.h"
32 #include "libutil/ringbuffer.h"
33
34 namespace Util {
35
36 class TimestampedBufferClient;
37
38 /**
39  * \brief Class implementing a frame buffer that is time-aware
40  *
41  * This class implements a buffer that is time-aware. Whenever new frames
42  * are written to the buffer, the timestamp corresponding to the last frame
43  * in the buffer is updated. This allows to calculate the timestamp of any
44  * other frame in the buffer.
45  *
46  * The buffer is a frame buffer, having the following parameters defining
47  * it's behaviour:
48  * - buff_size: buffer size in frames (setBufferSize())
49  * - events_per_frame: the number of events per frame (setEventsPerFrame())
50  * - event_size: the storage size of the events (in bytes) (setEventSize())
51  *
52  * The total size of the buffer (in bytes) is at least
53  * buff_size*events_per_frame*event_size.
54  *
55  * Timestamp tracking is done by requiring that a timestamp is specified every
56  * time frames are added to the buffer. In combination with the buffer fill and
57  * the frame rate (calculated internally), this allows to calculate the timestamp
58  * of any frame in the buffer. In order to initialize the internal data structures,
59  * the setNominalRate() and setUpdatePeriod() functions are provided.
60  *
61  * \note Currently the class only supports fixed size writes of size update_period.
62  *       This can change in the future, implementation ideas are already in place.
63  *
64  * The TimestampedBuffer class is time unit agnostic. It can handle any time unit
65  * as long as it fits in a 64 bit unsigned integer. The buffer supports wrapped
66  * timestamps using (...).
67  *
68  * There are two methods of reading and writing to the buffer.
69  *
70  * The first method uses conventional readFrames() and writeFrames() functions.
71  *
72  * The second method makes use of the TimestampedBufferClient interface. When a
73  * TimestampedBuffer is created, it is required that a TimestampedBufferClient is
74  * registered. This client implements the processReadBlock and processWriteBlock
75  * functions. These are block processing 'callbacks' that allow zero-copy processing
76  * of the buffer contents. In order to initiate block processing, the
77  * blockProcessWriteFrames and blockProcessReadFrames functions are provided by
78  * TimestampedBuffer.
79  *
80  */
81 class TimestampedBuffer {
82
83 public:
84
85
86     TimestampedBuffer(TimestampedBufferClient *);
87     virtual ~TimestampedBuffer();
88
89     bool writeFrames(unsigned int nbframes, char *data, uint64_t ts);
90     bool readFrames(unsigned int nbframes, char *data);
91
92     bool blockProcessWriteFrames(unsigned int nbframes, int64_t ts);
93     bool blockProcessReadFrames(unsigned int nbframes);
94
95     bool init();
96     bool prepare();
97     bool reset();
98
99     bool setEventSize(unsigned int s);
100     bool setEventsPerFrame(unsigned int s);
101     bool setBufferSize(unsigned int s);
102     unsigned int getBufferSize() {return m_buffer_size;};
103
104     bool setWrapValue(uint64_t w);
105
106     unsigned int getBufferFill();
107
108     // timestamp stuff
109     int getFrameCounter() {return m_framecounter;};
110
111     void getBufferHeadTimestamp(uint64_t *ts, uint64_t *fc);
112     void getBufferTailTimestamp(uint64_t *ts, uint64_t *fc);
113
114     void setBufferTailTimestamp(uint64_t new_timestamp);
115     void setBufferHeadTimestamp(uint64_t new_timestamp);
116
117     uint64_t getTimestampFromTail(int nframes);
118     uint64_t getTimestampFromHead(int nframes);
119
120     // buffer offset stuff
121     /// return the tick offset value
122     signed int getTickOffset() {return m_tick_offset;};
123
124     bool setFrameOffset(int nframes);
125     bool setTickOffset(int nframes);
126
127     // dll stuff
128     bool setNominalRate(float r);
129     float getRate();
130
131     bool setUpdatePeriod(unsigned int t);
132
133     // misc stuff
134     void dumpInfo();
135     void setVerboseLevel(int l) {setDebugLevel(l);};
136
137 private:
138     void decrementFrameCounter(int nbframes);
139     void incrementFrameCounter(int nbframes, uint64_t new_timestamp);
140     void resetFrameCounter();
141
142 protected:
143
144     ffado_ringbuffer_t * m_event_buffer;
145     char* m_cluster_buffer;
146
147     unsigned int m_event_size; // the size of one event
148     unsigned int m_events_per_frame; // the number of events in a frame
149     unsigned int m_buffer_size; // the number of frames in the buffer
150     unsigned int m_bytes_per_frame;
151     unsigned int m_bytes_per_buffer;
152
153     uint64_t m_wrap_at; // value to wrap at
154
155     TimestampedBufferClient *m_Client;
156
157     DECLARE_DEBUG_MODULE;
158
159 private:
160     // the framecounter gives the number of frames in the buffer
161     signed int m_framecounter;
162
163     // the offset that define the timing of the buffer
164     signed int m_tick_offset;
165
166     // the buffer tail timestamp gives the timestamp of the last frame
167     // that was put into the buffer
168     uint64_t   m_buffer_tail_timestamp;
169     uint64_t   m_buffer_next_tail_timestamp;
170
171     // this mutex protects the access to the framecounter
172     // and the buffer head timestamp.
173     pthread_mutex_t m_framecounter_lock;
174
175     // tracking DLL variables
176     float m_dll_e2;
177     float m_dll_b;
178     float m_dll_c;
179
180     float m_nominal_rate;
181     unsigned int m_update_period;
182 };
183
184 /**
185  * \brief Interface to be implemented by TimestampedBuffer clients
186  */
187 class TimestampedBufferClient {
188     public:
189         TimestampedBufferClient() {};
190         virtual ~TimestampedBufferClient() {};
191
192         virtual bool processReadBlock(char *data, unsigned int nevents, unsigned int offset)=0;
193         virtual bool processWriteBlock(char *data, unsigned int nevents, unsigned int offset)=0;
194
195 };
196
197 } // end of namespace Util
198
199 #endif /* __FFADO_TIMESTAMPEDBUFFER__ */
200
201
Note: See TracBrowser for help on using the browser.