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

Revision 2802, 8.1 kB (checked in by jwoithe, 3 years ago)

Cosmetic: "Firewire" becomes "FireWire?".

Officially both the "F" and "W" were capitalised in the FireWire? name, so
reflect this throughout FFADO's source tree. This mostly affects comments.

This patch originated from pander on the ffado-devel mailing list. To
maintain consistency, the committed version has been expanded to include
files not originally included in the original patch.

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.