libsdr  0.1.0
A simple SDR library
node.hh
1 
17 #ifndef __SDR_NODE_HH__
18 #define __SDR_NODE_HH__
19 
20 #include <set>
21 #include <list>
22 #include <iostream>
23 #include <complex>
24 #include <stdint.h>
25 #include <pthread.h>
26 
27 #include "buffer.hh"
28 #include "queue.hh"
29 #include "exception.hh"
30 
31 namespace sdr {
32 
35 class Config
36 {
37 public:
39  typedef enum {
40  Type_UNDEFINED = 0,
53  } Type;
54 
55 public:
57  Config();
59  Config(Type type, double sampleRate, size_t bufferSize, size_t numBuffers);
61  Config(const Config &other);
62 
64  const Config &operator= (const Config &other);
66  bool operator== (const Config &other) const;
67 
69  inline bool hasType() const { return Type_UNDEFINED != _type; }
71  inline Type type() const { return _type; }
73  inline void setType(Type type) { _type = type; }
75  inline bool hasSampleRate() const { return 0 != _sampleRate; }
77  inline double sampleRate() const { return _sampleRate; }
79  inline void setSampleRate(double rate) { _sampleRate = rate; }
81  inline bool hasBufferSize() const { return 0 != _bufferSize; }
83  inline size_t bufferSize() const { return _bufferSize; }
85  inline void setBufferSize(size_t size) { _bufferSize = size; }
87  inline bool hasNumBuffers() const { return 0 != _numBuffers; }
89  inline size_t numBuffers() const { return _numBuffers; }
91  inline void setNumBuffers(size_t N) { _numBuffers = N; }
92 
94  template <typename T> static inline Type typeId();
95 
96 protected:
100  double _sampleRate;
102  size_t _bufferSize;
104  size_t _numBuffers;
105 };
106 
108 template <>
109 inline Config::Type Config::typeId<uint8_t>() { return Type_u8; }
111 template <>
112 inline Config::Type Config::typeId<int8_t>() { return Type_s8; }
114 template <>
115 inline Config::Type Config::typeId<uint16_t>() { return Type_u16; }
117 template <>
118 inline Config::Type Config::typeId<int16_t>() { return Type_s16; }
120 template <>
121 inline Config::Type Config::typeId<float>() { return Type_f32; }
123 template <>
124 inline Config::Type Config::typeId<double>() { return Type_f64; }
126 template <>
127 inline Config::Type Config::typeId< std::complex<uint8_t> >() { return Type_cu8; }
129 template <>
130 inline Config::Type Config::typeId< std::complex<int8_t> >() { return Type_cs8; }
132 template <>
133 inline Config::Type Config::typeId< std::complex<uint16_t> >() { return Type_cu16; }
135 template <>
136 inline Config::Type Config::typeId< std::complex<int16_t> >() { return Type_cs16; }
138 template <>
139 inline Config::Type Config::typeId< std::complex<float> >() { return Type_cf32; }
141 template <>
142 inline Config::Type Config::typeId< std::complex<double> >() { return Type_cf64; }
143 
144 
146 inline const char *typeName(Config::Type type) {
147  switch (type) {
148  case Config::Type_UNDEFINED: return "UNDEFINED";
149  case Config::Type_u8: return "uint8";
150  case Config::Type_s8: return "int8";
151  case Config::Type_u16: return "uint16";
152  case Config::Type_s16: return "int16";
153  case Config::Type_f32: return "float";
154  case Config::Type_f64: return "double";
155  case Config::Type_cu8: return "complex uint8";
156  case Config::Type_cs8: return "complex int8";
157  case Config::Type_cu16: return "complex uint16";
158  case Config::Type_cs16: return "complex int16";
159  case Config::Type_cf32: return "complex float";
160  case Config::Type_cf64: return "complex double";
161  }
162  return "unknown";
163 }
164 
166 inline std::ostream &operator<<(std::ostream &stream, Config::Type type) {
167  stream << typeName(type) << " (" << (int)type << ")";
168  return stream;
169 }
170 
171 
174 class SinkBase
175 {
176 public:
178  SinkBase();
180  virtual ~SinkBase();
181 
183  virtual void handleBuffer(const RawBuffer &buffer, bool allow_overwrite) = 0;
185  virtual void config(const Config &src_cfg) = 0;
186 };
187 
188 
189 
191 template <class Scalar>
192 class Sink: public SinkBase
193 {
194 public:
196  Sink() : SinkBase() { }
198  virtual ~Sink() { }
199 
201  virtual void process(const Buffer<Scalar> &buffer, bool allow_overwrite) = 0;
202 
205  virtual void handleBuffer(const RawBuffer &buffer, bool allow_overwrite) {
206  this->process(Buffer<Scalar>(buffer), allow_overwrite);
207  }
208 };
209 
210 
211 
213 class Source
214 {
215 public:
217  Source();
219  virtual ~Source();
220 
222  virtual void send(const RawBuffer &buffer, bool allow_overwrite=false);
223 
225  void connect(SinkBase *sink, bool direct=false);
227  void disconnect(SinkBase *sink);
228 
231  virtual void setConfig(const Config &config);
232 
234  virtual double sampleRate() const;
236  virtual Config::Type type() const;
237 
239  template <class T>
240  void addEOS(T* instance, void (T::*function)()) {
241  _eos.push_back(new Delegate<T>(instance, function));
242  }
243 
244 protected:
246  void signalEOS();
247 
249  void propagateConfig(const Config &config);
250 
251 protected:
255  std::map<SinkBase *, bool> _sinks;
257  std::list<DelegateInterface *> _eos;
258 };
259 
260 
261 
267 class BlockingSource: public Source {
268 public:
276  BlockingSource(bool parallel=false, bool connect_idle=true, bool stop_queue_on_eos=false);
278  virtual ~BlockingSource();
279 
283  virtual void next() = 0;
284 
286  inline bool isActive() const { return _is_active; }
287 
289  virtual void start();
291  virtual void stop();
292 
293 protected:
295  void _parallel_main();
297  void _nonvirt_idle_cb();
298 
299 protected:
305  pthread_t _thread;
306 
307 private:
309  static void *_pthread_main_wrapper(void *);
310 };
311 
312 
315 class Proxy: public SinkBase, public Source
316 {
317 public:
319  Proxy();
321  virtual ~Proxy();
322 
324  virtual void config(const Config &src_cfg);
326  virtual void handleBuffer(const RawBuffer &buffer, bool allow_overwrite);
327 };
328 
329 
330 }
331 
332 #endif // __SDR_NODE_HH__
A collection of configuration information that is send by a source to all connected sinks to properga...
Definition: node.hh:35
Complex (aka I/Q) type of 32bit floats aka. std::complex.
Definition: node.hh:51
virtual void process(const Buffer< Scalar > &buffer, bool allow_overwrite)=0
Needs to be implemented by any sub-type to process the received data.
Base class of all buffers, represents an untyped array of bytes.
Definition: buffer.hh:32
virtual ~BlockingSource()
Destructor.
Definition: node.cc:149
Config _config
Holds the source configuration, this can be updated by calling setConfig.
Definition: node.hh:253
double _sampleRate
Holds the sample rate of the source.
Definition: node.hh:100
Specific delegate to a method of an object .
Definition: queue.hh:27
void propagateConfig(const Config &config)
Propagates the given configuration to all connected sinks.
Definition: node.cc:108
Config()
Empty constructor, will result into an invalid configuration.
Definition: node.cc:9
Source()
Constructor.
Definition: node.cc:56
const Config & operator=(const Config &other)
Assignment operator.
Definition: node.cc:29
Real signed 16b ints.
Definition: node.hh:44
virtual void send(const RawBuffer &buffer, bool allow_overwrite=false)
Sends the given buffer to all connected sinks.
Definition: node.cc:67
std::list< DelegateInterface * > _eos
The connected EOS singal handlers.
Definition: node.hh:257
Iterface of a blocking source.
Definition: node.hh:267
Typed sink.
Definition: node.hh:192
Complex (aka I/Q) type of unsigned 16b ints.
Definition: node.hh:49
bool _is_parallel
If true, the surce is processed in parallel.
Definition: node.hh:303
Definition: autocast.hh:8
size_t numBuffers() const
Returns the max.
Definition: node.hh:89
Type _type
Holds the type of the source.
Definition: node.hh:98
Real signed 8b ints.
Definition: node.hh:42
bool hasSampleRate() const
If true, the configuration has a sample rate.
Definition: node.hh:75
Generic source class.
Definition: node.hh:213
Real unsigned 8b ints.
Definition: node.hh:41
void _parallel_main()
The parallel main loop.
Definition: node.cc:172
void signalEOS()
Signals the EOS.
Definition: node.cc:127
virtual ~Proxy()
Destructor.
Definition: node.cc:203
bool hasType() const
If true, the configuration has a type.
Definition: node.hh:69
std::map< SinkBase *, bool > _sinks
The connected sinks.
Definition: node.hh:255
Real 64b floats aka. "double".
Definition: node.hh:46
virtual double sampleRate() const
Returns the configured sample rate or 0 otherwise.
Definition: node.cc:122
virtual ~Sink()
Drestructor.
Definition: node.hh:198
bool isActive() const
Returns true if the source is active.
Definition: node.hh:286
Real unsigned 16b ints.
Definition: node.hh:43
virtual void setConfig(const Config &config)
Stores the configuration and propergates it if the configuration has been changed.
Definition: node.cc:98
bool _is_active
If true, the source is active.
Definition: node.hh:301
virtual void config(const Config &src_cfg)
Configures the node.
Definition: node.cc:208
virtual void next()=0
This method gets called either by the Queue on idle events or by a thread to read more data from the ...
virtual void config(const Config &src_cfg)=0
Needs to be implemented by any sub-type to check and perform the configuration of the node...
void connect(SinkBase *sink, bool direct=false)
Connect this source to a sink.
Definition: node.cc:87
virtual void handleBuffer(const RawBuffer &buffer, bool allow_overwrite)=0
Needs to be implemented by any sub-type to process the received data.
void setNumBuffers(size_t N)
Sets the max.
Definition: node.hh:91
size_t _bufferSize
Holds the max.
Definition: node.hh:102
Type type() const
Returns the type.
Definition: node.hh:71
Proxy()
Constructor.
Definition: node.cc:197
virtual void start()
This function starts the input stream.
Definition: node.cc:154
pthread_t _thread
The thread of the source.
Definition: node.hh:305
void setType(Type type)
Sets the type.
Definition: node.hh:73
Sink()
Constructor.
Definition: node.hh:196
static Type typeId()
Returns the type-id of the template type.
SinkBase()
Constructor.
Definition: node.cc:45
Real 32b floats aka. "float".
Definition: node.hh:45
bool hasNumBuffers() const
If true, the configuration has a number of buffers.
Definition: node.hh:87
size_t bufferSize() const
Returns the max.
Definition: node.hh:83
virtual void stop()
This function stops the input stream.
Definition: node.cc:162
Type
The type IDs.
Definition: node.hh:39
Basic interface of all Sinks.
Definition: node.hh:174
virtual ~Source()
Destructor.
Definition: node.cc:62
void setSampleRate(double rate)
Sets the sample rate.
Definition: node.hh:79
Complex (aka I/Q) type of signed 8b ints.
Definition: node.hh:48
virtual void handleBuffer(const RawBuffer &buffer, bool allow_overwrite)
Forwards the buffer.
Definition: node.cc:213
bool operator==(const Config &other) const
Coparison operator.
Definition: node.cc:36
Complex (aka I/Q) type of signed 16b ints.
Definition: node.hh:50
Complex (aka I/Q) type of unsigned 8b ints.
Definition: node.hh:47
virtual Config::Type type() const
Returns the configured source type or Config::Type_UNDEFINED otherwise.
Definition: node.cc:117
A NOP node.
Definition: node.hh:315
BlockingSource(bool parallel=false, bool connect_idle=true, bool stop_queue_on_eos=false)
Constructor.
Definition: node.cc:137
void disconnect(SinkBase *sink)
Disconnect a sink again.
Definition: node.cc:93
void addEOS(T *instance, void(T::*function)())
Adds a callback to the end-of-stream signal of the source.
Definition: node.hh:240
void _nonvirt_idle_cb()
The non-virtual idle callback.
Definition: node.cc:179
virtual void handleBuffer(const RawBuffer &buffer, bool allow_overwrite)
Re-implemented from SinkBase.
Definition: node.hh:205
virtual ~SinkBase()
Destructor.
Definition: node.cc:49
void setBufferSize(size_t size)
Sets the max.
Definition: node.hh:85
bool hasBufferSize() const
If true, the configuration has a buffer size.
Definition: node.hh:81
Complex (aka I/Q) type of 64bit floats aka. std::complex.
Definition: node.hh:52
size_t _numBuffers
Holds the max.
Definition: node.hh:104
double sampleRate() const
Returns the sample rate.
Definition: node.hh:77