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

Revision 864, 8.3 kB (checked in by ppalmers, 15 years ago)

update license to GPLv2 or GPLv3 instead of GPLv2 or any later version. Update copyrights to reflect the new year

Line 
1 /*
2  * Copyright (C) 2005-2008 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 program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 #ifndef __FFADO_TIMESTAMPEDBUFFER__
25 #define __FFADO_TIMESTAMPEDBUFFER__
26
27 #include "../debugmodule/debugmodule.h"
28 #include "libutil/ringbuffer.h"
29 #include <pthread.h>
30
31 //typedef float ffado_timestamp_t;
32 //#define TIMESTAMP_FORMAT_SPEC "%14.3f"
33 typedef double ffado_timestamp_t;
34 #define TIMESTAMP_FORMAT_SPEC "%14.3f"
35 // typedef int64_t ffado_timestamp_t;
36 // #define TIMESTAMP_FORMAT_SPEC "%012lld"
37
38 namespace Util
39 {
40
41 class TimestampedBufferClient;
42
43 /**
44     * \brief Class implementing a frame buffer that is time-aware
45     *
46     * This class implements a buffer that is time-aware. Whenever new frames
47     * are written to the buffer, the timestamp corresponding to the last frame
48     * in the buffer is updated. This allows to calculate the timestamp of any
49     * other frame in the buffer.
50     *
51     * The buffer is a frame buffer, having the following parameters defining
52     * it's behaviour:
53     * - buff_size: buffer size in frames (setBufferSize())
54     * - events_per_frame: the number of events per frame (setEventsPerFrame())
55     * - event_size: the storage size of the events (in bytes) (setEventSize())
56     *
57     * The total size of the buffer (in bytes) is at least
58     * buff_size*events_per_frame*event_size.
59     *
60     * Timestamp tracking is done by requiring that a timestamp is specified every
61     * time frames are added to the buffer. In combination with the buffer fill and
62     * the frame rate (calculated internally), this allows to calculate the timestamp
63     * of any frame in the buffer. In order to initialize the internal data structures,
64     * the setNominalRate() and setUpdatePeriod() functions are provided.
65     *
66     * \note Currently the class only supports fixed size writes of size update_period.
67     *       This can change in the future, implementation ideas are already in place.
68     *
69     * The TimestampedBuffer class is time unit agnostic. It can handle any time unit
70     * as long as it fits in a 64 bit unsigned integer. The buffer supports wrapped
71     * timestamps using (...).
72     *
73     * There are two methods of reading and writing to the buffer.
74     *
75     * The first method uses conventional readFrames() and writeFrames() functions.
76     *
77     * The second method makes use of the TimestampedBufferClient interface. When a
78     * TimestampedBuffer is created, it is required that a TimestampedBufferClient is
79     * registered. This client implements the processReadBlock and processWriteBlock
80     * functions. These are block processing 'callbacks' that allow zero-copy processing
81     * of the buffer contents. In order to initiate block processing, the
82     * blockProcessWriteFrames and blockProcessReadFrames functions are provided by
83     * TimestampedBuffer.
84     *
85     */
86 class TimestampedBuffer
87 {
88     public:
89         TimestampedBuffer ( TimestampedBufferClient * );
90         virtual ~TimestampedBuffer();
91
92         bool writeDummyFrame();
93         bool dropFrames ( unsigned int nbframes );
94
95         bool writeFrames ( unsigned int nbframes, char *data, ffado_timestamp_t ts );
96         bool readFrames ( unsigned int nbframes, char *data );
97
98         bool preloadFrames ( unsigned int nbframes, char *data, bool keep_head_ts );
99
100         bool blockProcessWriteFrames ( unsigned int nbframes, ffado_timestamp_t ts );
101         bool blockProcessReadFrames ( unsigned int nbframes );
102
103         bool prepare();
104         bool clearBuffer();
105
106         bool isEnabled() {return m_enabled;};
107         void enable() {m_enabled=true;};
108         void disable() {m_enabled=false;};
109
110         bool isTransparent() {return m_transparent;};
111         void setTransparent ( bool v ) {m_transparent=v;};
112
113         bool setEventSize ( unsigned int s );
114         bool setEventsPerFrame ( unsigned int s );
115         bool setBufferSize ( unsigned int s );
116         unsigned int getBufferSize() {return m_buffer_size;};
117
118         unsigned int getBytesPerFrame() {return m_bytes_per_frame;};
119
120         bool setWrapValue ( ffado_timestamp_t w );
121
122         unsigned int getBufferFill();
123         unsigned int getBufferSpace();
124
125         // timestamp stuff
126         int getFrameCounter() {return m_framecounter;};
127
128         void getBufferHeadTimestamp ( ffado_timestamp_t *ts, signed int *fc );
129         void getBufferTailTimestamp ( ffado_timestamp_t *ts, signed int *fc );
130
131         void setBufferTailTimestamp ( ffado_timestamp_t new_timestamp );
132         void setBufferHeadTimestamp ( ffado_timestamp_t new_timestamp );
133
134         // sync related, also drops or add frames when necessary
135         bool syncBufferHeadToTimestamp ( ffado_timestamp_t ts );
136         bool syncBufferTailToTimestamp ( ffado_timestamp_t ts );
137         bool syncCorrectLag ( int64_t ts );
138
139         ffado_timestamp_t getTimestampFromTail ( int nframes );
140         ffado_timestamp_t getTimestampFromHead ( int nframes );
141
142         // buffer offset stuff
143         /// return the tick offset value
144         ffado_timestamp_t getTickOffset() {return m_tick_offset;};
145
146         bool setFrameOffset ( int nframes );
147         bool setTickOffset ( ffado_timestamp_t );
148
149         // dll stuff
150         bool setNominalRate ( float r );
151         float getNominalRate() {return m_nominal_rate;};
152         float getRate();
153
154         bool setUpdatePeriod ( unsigned int t );
155         unsigned int getUpdatePeriod();
156
157         // misc stuff
158         void dumpInfo();
159         void setVerboseLevel ( int l ) {setDebugLevel ( l );};
160
161     private:
162         void decrementFrameCounter(unsigned int nbframes);
163         void incrementFrameCounter(unsigned int nbframes, ffado_timestamp_t new_timestamp);
164         void resetFrameCounter();
165
166     protected:
167
168         ffado_ringbuffer_t * m_event_buffer;
169         char* m_process_buffer;
170         unsigned int m_cluster_size;
171         unsigned int m_process_block_size;
172
173         unsigned int m_event_size; // the size of one event
174         unsigned int m_events_per_frame; // the number of events in a frame
175         unsigned int m_buffer_size; // the number of frames in the buffer
176         unsigned int m_bytes_per_frame;
177         unsigned int m_bytes_per_buffer;
178         bool m_enabled; // you can get frames FIXME: rename!!
179         bool m_transparent; // the buffer should hold the frames put in it. if true, discards all frames
180
181         ffado_timestamp_t m_wrap_at; // value to wrap at
182
183         TimestampedBufferClient *m_Client;
184
185         DECLARE_DEBUG_MODULE;
186
187     private:
188         // the framecounter gives the number of frames in the buffer
189         signed int m_framecounter;
190
191         // the offset that define the timing of the buffer
192         ffado_timestamp_t m_tick_offset;
193
194         // the buffer tail timestamp gives the timestamp of the last frame
195         // that was put into the buffer
196         ffado_timestamp_t   m_buffer_tail_timestamp;
197         ffado_timestamp_t   m_buffer_next_tail_timestamp;
198
199         // this mutex protects the access to the framecounter
200         // and the buffer head timestamp.
201         pthread_mutex_t m_framecounter_lock;
202
203         // tracking DLL variables
204 // JMW: try double for this too
205 //    float m_dll_e2;
206         double m_dll_e2;
207         float m_dll_b;
208         float m_dll_c;
209
210         float m_nominal_rate;
211         float calculateRate();
212         float m_current_rate;
213         unsigned int m_update_period;
214 };
215
216 /**
217     * \brief Interface to be implemented by TimestampedBuffer clients
218     */
219 class TimestampedBufferClient
220 {
221     public:
222         TimestampedBufferClient() {};
223         virtual ~TimestampedBufferClient() {};
224
225         virtual bool processReadBlock ( char *data, unsigned int nevents, unsigned int offset ) =0;
226         virtual bool processWriteBlock ( char *data, unsigned int nevents, unsigned int offset ) =0;
227
228 };
229
230 } // end of namespace Util
231
232 #endif /* __FFADO_TIMESTAMPEDBUFFER__ */
233
234
Note: See TracBrowser for help on using the browser.