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

Revision 554, 6.9 kB (checked in by ppalmers, 14 years ago)

Merge echoaudio branch into trunk.

This adds support for the Echo Audiofire devices to FFADO. Possibly also other devices working with the Apple Class Driver will work with this code. It is not fully complete yet, but the main rework is
done.

First of all the IAvDevice class/interface is renamed to FFADODevice, in order to separate the AV/C code from the FFADO API code. A device supported by FFADO implements a FFADODevice.

The BeBoB device has been split up into three groups:
- libavc/* : all code and commands that are specified by AV/C specs. Note that a lot of the code that used to be in BeBoB::AvDevice? now resides in AVC::Unit
- genericavc/* : a FFADODevice that uses AV/C descriptors & commands for discovery and config
- bebob/* : the bebob FFADODevice that inherits from GenericAVC::AvDevice? but that uses BridgeCo? commands for discovery

Everything has been moved as high as possible in the class hierarchy. If necessary, a subclass that uses device specific commands is introduced (e.g. BeBoB::Plug inherits from AVC::Plug and uses the
BridgeCo? extended plug info command to discover it's properties).

There are some other fixes along the way that have been done too.

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