Essentia  2.1-beta5-dev
phantombuffer.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2016 Music Technology Group - Universitat Pompeu Fabra
3  *
4  * This file is part of Essentia
5  *
6  * Essentia is free software: you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License as published by the Free
8  * Software Foundation (FSF), either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the Affero GNU General Public License
17  * version 3 along with this program. If not, see http://www.gnu.org/licenses/
18  */
19 
20 #ifndef ESSENTIA_PHANTOMBUFFER_H
21 #define ESSENTIA_PHANTOMBUFFER_H
22 
23 #include <vector>
24 #include "multiratebuffer.h"
25 #include "../roguevector.h"
26 #include "../threading.h"
27 #include "../essentiautil.h"
28 
29 
30 namespace essentia {
31 namespace streaming {
32 
33 class Window {
34  public:
35  int begin;
36  int end;
37  int turn;
38 
39  Window() : begin(0), end(0), turn(0) {}
40 
41  inline int total(int bufferSize) const {
42  return turn*bufferSize + begin;
43  }
44 };
45 
46 
59 template <typename T>
60 class PhantomBuffer : public MultiRateBuffer<T> {
61 
62  public:
63 
65  _parent = parent;
66  setBufferType(type);
67  }
68 
70  BufferInfo buf;
71  switch (type) {
73  buf.size = 16;
74  buf.maxContiguousElements = 0;
75  break;
76 
78  buf.size = 262144;
79  buf.maxContiguousElements = 32768;
80  break;
81 
83  buf.size = 65536;
84  buf.maxContiguousElements = 4096;
85  break;
86 
88  buf.size = 1048576;
89  buf.maxContiguousElements = 262144;
90  break;
91 
92  default:
93  throw EssentiaException("Unknown buffer type");
94  }
95 
96  setBufferInfo(buf);
97  }
98 
100  BufferInfo info;
101  info.size = _bufferSize;
102  info.maxContiguousElements = _phantomSize;
103  return info;
104  }
105 
106  void setBufferInfo(const BufferInfo& info) {
107  _bufferSize = info.size;
108  _phantomSize = info.maxContiguousElements;
109  _buffer.resize(_bufferSize + _phantomSize);
110  }
111 
112  PhantomBuffer(SourceBase* parent, int size, int phantomSize) :
113  _parent(parent),
114  _bufferSize(size),
115  _phantomSize(phantomSize),
116  _buffer(size + phantomSize) {
117  // initialize views and all??
118  }
119 
124 
125  const std::vector<T>& readView(ReaderID id) const;
126  std::vector<T>& writeView() { return _writeView; }
127 
132  bool acquireForRead(ReaderID id, int requested);
133 
138  bool acquireForWrite(int requested);
139 
140  void releaseForWrite(int released);
141  void releaseForRead(ReaderID id, int released);
142 
143  // @todo mutex-lock these functions or not??
151  ReaderID addReader(bool startFromZero = false);
152  void removeReader(ReaderID id);
153 
154  int numberReaders() const;
155 
162  void resize(int size, int phantomSize) {
163  _buffer.resize(size+phantomSize);
164  _bufferSize = size;
165  _phantomSize = phantomSize;
166  }
167 
168  int totalTokensWritten() const {
169  MutexLocker lock(mutex); NOWARN_UNUSED(lock);
170  return _writeWindow.total(_bufferSize);
171  }
172 
173  int totalTokensRead(ReaderID id) const {
174  MutexLocker lock(mutex); NOWARN_UNUSED(lock);
175  return _readWindow[id].total(_bufferSize);
176  }
177 
178  const T& lastTokenProduced() const {
179  MutexLocker lock(mutex); NOWARN_UNUSED(lock);
180  if (_writeWindow.total(_bufferSize) == 0) {
181  throw EssentiaException("Tried to call ::lastTokenProduced() on ", _parent->fullName(),
182  " which hasn't produced any token yet");
183  }
184 
185  int idx = _writeWindow.begin;
186  if (idx == 0) return _buffer[_bufferSize-1];
187  return _buffer[idx-1];
188  }
189 
190  void reset();
191 
192  protected:
194 
195  int _bufferSize, _phantomSize; // bufferSize does not include phantomSize
196  std::vector<T> _buffer; // the buffer where data is stored
197  // bufferSize must be > phantomSize in all cases
198 
200  std::vector<Window> _readWindow;
201 
203  std::vector<RogueVector<T> > _readView; // @todo CAREFUL WHEN COPYING ROGUEVECTOR...
204 
205  // threading-related & locking structures
206  mutable Mutex mutex; // should be locked before any modification to the object
207 
208  protected:
209  // this function is only here to make sure we do not overflow the window.turn variable
210  // @todo we could make the class smarter by not counting the turns, but just knowing if
211  // readers are on the same turn as the writer, or if they're one turn late (use a bool
212  // isTurnOdd (or even))
213  void resetTurns();
214 
215  void updateReadView(ReaderID id);
216  void updateWriteView();
217 
218  // mutex should be locked before entering this function
219  // make sure it doesn't overflow
220  int availableForRead(ReaderID id) const;
221  int availableForWrite(bool contiguous=true) const;
222 
223  // reposition pointer if we're in the phantom zone
224  void relocateReadWindow(ReaderID id);
225  void relocateWriteWindow();
226 
227 };
228 
229 } // namespace streaming
230 } // namespace essentia
231 
232 #include "phantombuffer_impl.h"
233 
234 #endif // ESSENTIA_PHANTOMBUFFER_H
int maxContiguousElements
Definition: types.h:384
void resize(int size, int phantomSize)
Definition: phantombuffer.h:162
int ReaderID
Definition: types.h:343
PhantomBuffer(SourceBase *parent, BufferUsage::BufferUsageType type)
Definition: phantombuffer.h:64
void setBufferInfo(const BufferInfo &info)
Definition: phantombuffer.h:106
Definition: sourcebase.h:52
std::vector< RogueVector< T > > _readView
Definition: phantombuffer.h:203
PhantomBuffer(SourceBase *parent, int size, int phantomSize)
Definition: phantombuffer.h:112
Definition: roguevector.h:30
int end
Definition: phantombuffer.h:36
Window()
Definition: phantombuffer.h:39
std::vector< T > _buffer
Definition: phantombuffer.h:196
BufferUsageType
Definition: types.h:397
Definition: phantombuffer.h:60
int totalTokensWritten() const
Definition: phantombuffer.h:168
Definition: phantombuffer.h:33
const T & lastTokenProduced() const
Definition: phantombuffer.h:178
void setBufferType(BufferUsage::BufferUsageType type)
Definition: phantombuffer.h:69
int begin
Definition: phantombuffer.h:35
SourceBase * _parent
Definition: phantombuffer.h:193
std::vector< Window > _readWindow
Definition: phantombuffer.h:200
int turn
Definition: phantombuffer.h:37
RogueVector< T > _writeView
Definition: phantombuffer.h:202
std::vector< T > & writeView()
Definition: phantombuffer.h:126
Definition: types.h:381
Definition: algorithm.h:28
Definition: types.h:76
Definition: threading.h:51
~PhantomBuffer()
Definition: phantombuffer.h:123
#define NOWARN_UNUSED(expr)
Definition: essentiautil.h:42
Mutex mutex
Definition: phantombuffer.h:206
Definition: threading.h:45
int totalTokensRead(ReaderID id) const
Definition: phantombuffer.h:173
Window _writeWindow
Definition: phantombuffer.h:199
int _phantomSize
Definition: phantombuffer.h:195
int total(int bufferSize) const
Definition: phantombuffer.h:41
BufferInfo bufferInfo() const
Definition: phantombuffer.h:99
Definition: multiratebuffer.h:30
int size
Definition: types.h:383