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

Revision 1972, 8.1 kB (checked in by jwoithe, 10 years ago)

- Parameterise selected low-level error detection thresholds. The default values are those which have been used up to now, so no functional changes should result from this.
- RME: attempt to use the main DLL without a smoothing DLL in front of it since this may track the current timestamp better. Broaden various lower level error thresholds of RME objects accordingly. Testing continues.

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