Essentia  2.1-beta6-dev
sink.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2021 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_SINK_H
21 #define ESSENTIA_SINK_H
22 
23 #include "multiratebuffer.h"
24 #include "sinkproxy.h"
25 
26 namespace essentia {
27 namespace streaming {
28 
29 
30 template <typename TokenType>
31 class Source;
32 
33 // also known as Input-port, InputDataStream
34 template <typename TokenType>
35 class Sink : public SinkBase {
36  USE_TYPE_INFO(TokenType);
37 
38  public:
39 
40  Sink(Algorithm* parent = 0, const std::string& name = "unnamed") :
41  SinkBase(parent, name) {}
42 
43  Sink(const std::string& name) : SinkBase(name) {}
44 
45  inline const MultiRateBuffer<TokenType>& buffer() const {
46  if (_source) return *static_cast<const MultiRateBuffer<TokenType>*>(_source->buffer());
47  else if (_sproxy) return *static_cast<const MultiRateBuffer<TokenType>*>(_sproxy->buffer());
48  else
49  throw EssentiaException("Sink ", fullName(), " is not currently connected to another Source");
50  }
51 
53  if (_source) return *static_cast<MultiRateBuffer<TokenType>*>(_source->buffer());
54  else if (_sproxy) return *static_cast<MultiRateBuffer<TokenType>*>(_sproxy->buffer());
55  else
56  throw EssentiaException("Sink ", fullName(), " is not currently connected to another Source");
57  }
58 
59 
60  const std::vector<TokenType>& tokens() const { return buffer().readView(_id); }
61  const TokenType& firstToken() const { return buffer().readView(_id)[0]; }
62  const TokenType& lastTokenProduced() const { return buffer().lastTokenProduced(); }
63 
64  virtual const void* getTokens() const { return &tokens(); }
65  virtual const void* getFirstToken() const { return &firstToken(); }
66 
67  inline void acquire() { StreamConnector::acquire(); }
68 
69  virtual bool acquire(int n) {
70  if (_source) return buffer().acquireForRead(_id, n);
71  // NOTE: do not call buffer() here because we would have to give an ID which we're not sure is correct
72  // this however makes the previous case (if _source) check for _source twice, and is generally less
73  // beautiful. We should find a way to have the ID always synchronized to make the code cleaner
74  else if (_sproxy) return _sproxy->acquire(n);
75  else
76  throw EssentiaException("Cannot acquire for sink ", fullName(), ", which has not been connected.");
77  }
78 
79  inline void release() { StreamConnector::release(); }
80 
81  virtual void release(int n) {
82  if (_source) return buffer().releaseForRead(_id, n);
83  else if (_sproxy) return _sproxy->release(n);
84  else
85  throw EssentiaException("Cannot release for sink ", fullName(), ", which has not been connected.");
86  }
87 
88  virtual int available() const {
89  if (_source) return buffer().availableForRead(_id);
90  else if (_sproxy) return _sproxy->available();
91  else
92  throw EssentiaException("Cannot get number of available tokens for sink ", fullName(),
93  ", which has not been connected.");
94  }
95 
96  virtual void reset() {}
97 
98  TokenType pop() {
99  if (!acquire(1))
100  throw EssentiaException("No more tokens available to pop in ", fullName());
101 
102  TokenType result = *(TokenType*)getFirstToken();
103  release(1);
104 
105  return result;
106  }
107 
108 
109 };
110 
111 
112 } // namespace streaming
113 } // namespace essentia
114 
115 
116 #endif // ESSENTIA_SINK_H
Definition: types.h:77
const std::string & name() const
Definition: types.h:284
Definition: streamingalgorithm.h:140
std::string fullName() const
const Algorithm * parent() const
Definition: connector.h:53
virtual const std::vector< T > & readView(ReaderID id) const =0
virtual void releaseForRead(ReaderID id, int released)=0
virtual int availableForRead(ReaderID id) const =0
virtual bool acquireForRead(ReaderID id, int requested)=0
virtual const T & lastTokenProduced() const =0
Definition: sinkbase.h:52
SinkProxyBase * _sproxy
Definition: sinkbase.h:57
ReaderID _id
Definition: sinkbase.h:55
SourceBase * _source
Definition: sinkbase.h:54
void release()
Definition: sinkproxy.h:86
const void * buffer() const
Definition: sinkproxy.h:46
void acquire()
Definition: sinkproxy.h:73
Definition: sink.h:35
const std::vector< TokenType > & tokens() const
Definition: sink.h:60
virtual bool acquire(int n)
Definition: sink.h:69
void release()
Definition: sink.h:79
virtual int available() const
Definition: sink.h:88
TokenType pop()
Definition: sink.h:98
virtual void reset()
Definition: sink.h:96
MultiRateBuffer< TokenType > & buffer()
Definition: sink.h:52
const TokenType & firstToken() const
Definition: sink.h:61
const TokenType & lastTokenProduced() const
Definition: sink.h:62
const MultiRateBuffer< TokenType > & buffer() const
Definition: sink.h:45
Sink(const std::string &name)
Definition: sink.h:43
virtual void release(int n)
Definition: sink.h:81
virtual const void * getFirstToken() const
Definition: sink.h:65
Sink(Algorithm *parent=0, const std::string &name="unnamed")
Definition: sink.h:40
void acquire()
Definition: sink.h:67
virtual const void * getTokens() const
Definition: sink.h:64
void release()
Definition: streamconnector.h:59
bool acquire()
Definition: streamconnector.h:49
virtual int available() const =0
Definition: algorithm.h:28
#define USE_TYPE_INFO(TokenType)
Definition: types.h:332