libsdr  0.1.0
A simple SDR library
buffernode.hh
1 #ifndef __SDR_BUFFERNODE_HH__
2 #define __SDR_BUFFERNODE_HH__
3 
4 #include "node.hh"
5 #include "config.hh"
6 #include "logger.hh"
7 
8 #include <iostream>
9 #include <cstring>
10 
11 
12 namespace sdr {
13 
17 template <class Scalar>
18 class BufferNode : public Sink<Scalar>, public Source
19 {
20 public:
23  BufferNode(size_t bufferSize)
24  : _bufferSize(bufferSize), _bufferSet(0, _bufferSize), _temp(bufferSize), _samplesLeft(0)
25  {
26  // pass...
27  }
28 
30  virtual void config(const Config &src_cfg)
31  {
32  // Check if source config is complete
33  if (Config::Type_UNDEFINED == src_cfg.type()) { return; }
34  if (0 == src_cfg.bufferSize()) { return; }
35  if (0 == src_cfg.numBuffers()) { return; }
36  // Check source type
37  if (src_cfg.type() != Config::typeId<Scalar>()) {
38  ConfigError err;
39  err << "Can not configure BufferNode sink. Source type is " << src_cfg.type()
40  << " expected " << Config::typeId<Scalar>() << std::endl;
41  throw err;
42  }
43  // Estimate number of buffers needed:
44  size_t totSize = src_cfg.bufferSize()*src_cfg.numBuffers();
45  size_t numBuffers = std::max(size_t(2), totSize/_bufferSize);
46  _bufferSet.resize(numBuffers);
47 
48  LogMessage msg(LOG_DEBUG);
49  msg << "Configure BufferNode: " << std::endl
50  << " type: " << src_cfg.type() << std::endl
51  << " sample-rate: " << src_cfg.sampleRate() << std::endl
52  << " buffer-size: " << src_cfg.bufferSize()
53  << " -> " << _bufferSize << std::endl
54  << " # buffers: " << src_cfg.numBuffers();
55 
56  // Propergate source config
57  this->setConfig(Config(src_cfg.type(), src_cfg.sampleRate(), _bufferSize, numBuffers));
58  }
59 
61  virtual void process(const Buffer<Scalar> &buffer, bool allow_overwrite)
62  {
63  // If the current buffer buffer does not contain enough smaples to fill an output buffer:
64  if ((_samplesLeft+buffer.size()) < _bufferSize) {
65  memcpy(_temp.data()+_samplesLeft*sizeof(Scalar), buffer.data(), sizeof(Scalar)*buffer.size());
66  _samplesLeft += buffer.size();
67  return;
68  }
69  // There are enough samples collected to fill an ouput buffer,
70  // fill first out buffer and send it
71  Buffer<Scalar> out = _bufferSet.getBuffer();
72  memcpy(out.data(), _temp.data(), sizeof(Scalar)*_samplesLeft);
73  memcpy(out.data()+_samplesLeft*sizeof(Scalar), buffer.data(), sizeof(Scalar)*(_bufferSize-_samplesLeft));
74  size_t in_offset = (_bufferSize-_samplesLeft);
75 
76  // Determine the number of samples left
78  this->send(out);
79 
80  // Process remaining data
81  while (_samplesLeft >= _bufferSize) {
82  Buffer<Scalar> out = _bufferSet.getBuffer();
83  memcpy(out.data(), buffer.data()+in_offset*sizeof(Scalar), _bufferSize*sizeof(Scalar));
84  in_offset += _bufferSize;
86  this->send(out);
87  }
88 
89  // Store data left over into temp
90  memcpy(_temp.data(), buffer.data(), _samplesLeft*sizeof(Scalar));
91  }
92 
93 protected:
95  size_t _bufferSize;
101  size_t _samplesLeft;
102 };
103 
104 }
105 
106 #endif // __SDR_BUFFERNODE_HH__
A collection of configuration information that is send by a source to all connected sinks to properga...
Definition: node.hh:35
virtual void process(const Buffer< Scalar > &buffer, bool allow_overwrite)
Process the incomming data.
Definition: buffernode.hh:61
virtual void send(const RawBuffer &buffer, bool allow_overwrite=false)
Sends the given buffer to all connected sinks.
Definition: node.cc:67
BufferNode(size_t bufferSize)
Constructs a new buffer node.
Definition: buffernode.hh:23
Typed sink.
Definition: node.hh:192
Definition: autocast.hh:8
size_t numBuffers() const
Returns the max.
Definition: node.hh:89
Generic source class.
Definition: node.hh:213
size_t _bufferSize
The desired buffer size.
Definition: buffernode.hh:95
size_t size() const
Returns the number of elements of type T in this buffer.
Definition: buffer.hh:166
A set of buffers, that tracks their usage.
Definition: buffer.hh:288
A simple buffering node, that ensures a fixed buffer size.
Definition: buffernode.hh:18
char * data() const
Returns the pointer to the data of the buffer view.
Definition: buffer.hh:69
size_t _samplesLeft
Number of samples left.
Definition: buffernode.hh:101
virtual void setConfig(const Config &config)
Stores the configuration and propergates it if the configuration has been changed.
Definition: node.cc:98
Buffer< Scalar > _temp
An intermediate buffer to hold left-over samples from the previous buffers.
Definition: buffernode.hh:99
Type type() const
Returns the type.
Definition: node.hh:71
The configuration error class.
Definition: exception.hh:24
A log message.
Definition: logger.hh:22
size_t bufferSize() const
Returns the max.
Definition: node.hh:83
BufferSet< Scalar > _bufferSet
A set of output buffers.
Definition: buffernode.hh:97
virtual void config(const Config &src_cfg)
Configures the buffer node.
Definition: buffernode.hh:30
double sampleRate() const
Returns the sample rate.
Definition: node.hh:77