buffernode.hh
#ifndef __SDR_BUFFERNODE_HH__
#define __SDR_BUFFERNODE_HH__
#include "node.hh"
#include "config.hh"
#include "logger.hh"
#include <iostream>
#include <cstring>
namespace sdr {
template <class Scalar>
class BufferNode : public Sink<Scalar>, public Source
{
public:
BufferNode(size_t bufferSize)
: _bufferSize(bufferSize), _bufferSet(0, _bufferSize), _temp(bufferSize), _samplesLeft(0)
{
// pass...
}
virtual void config(const Config &src_cfg)
{
// Check if source config is complete
if (Config::Type_UNDEFINED == src_cfg.type()) { return; }
if (0 == src_cfg.bufferSize()) { return; }
if (0 == src_cfg.numBuffers()) { return; }
// Check source type
if (src_cfg.type() != Config::typeId<Scalar>()) {
ConfigError err;
err << "Can not configure BufferNode sink. Source type is " << src_cfg.type()
<< " expected " << Config::typeId<Scalar>() << std::endl;
throw err;
}
// Estimate number of buffers needed:
size_t totSize = src_cfg.bufferSize()*src_cfg.numBuffers();
size_t numBuffers = std::max(size_t(2), totSize/_bufferSize);
_bufferSet.resize(numBuffers);
LogMessage msg(LOG_DEBUG);
msg << "Configure BufferNode: " << std::endl
<< " type: " << src_cfg.type() << std::endl
<< " sample-rate: " << src_cfg.sampleRate() << std::endl
<< " buffer-size: " << src_cfg.bufferSize()
<< " -> " << _bufferSize << std::endl
<< " # buffers: " << src_cfg.numBuffers();
// Propergate source config
this->setConfig(Config(src_cfg.type(), src_cfg.sampleRate(), _bufferSize, numBuffers));
}
virtual void process(const Buffer<Scalar> &buffer, bool allow_overwrite)
{
// If the current buffer buffer does not contain enough smaples to fill an output buffer:
if ((_samplesLeft+buffer.size()) < _bufferSize) {
memcpy(_temp.data()+_samplesLeft*sizeof(Scalar), buffer.data(), sizeof(Scalar)*buffer.size());
_samplesLeft += buffer.size();
return;
}
// There are enough samples collected to fill an ouput buffer,
// fill first out buffer and send it
Buffer<Scalar> out = _bufferSet.getBuffer();
memcpy(out.data(), _temp.data(), sizeof(Scalar)*_samplesLeft);
memcpy(out.data()+_samplesLeft*sizeof(Scalar), buffer.data(), sizeof(Scalar)*(_bufferSize-_samplesLeft));
size_t in_offset = (_bufferSize-_samplesLeft);
// Determine the number of samples left
_samplesLeft = buffer.size()+_samplesLeft-_bufferSize;
this->send(out);
// Process remaining data
while (_samplesLeft >= _bufferSize) {
Buffer<Scalar> out = _bufferSet.getBuffer();
memcpy(out.data(), buffer.data()+in_offset*sizeof(Scalar), _bufferSize*sizeof(Scalar));
in_offset += _bufferSize;
_samplesLeft -= _bufferSize;
this->send(out);
}
// Store data left over into temp
memcpy(_temp.data(), buffer.data(), _samplesLeft*sizeof(Scalar));
}
protected:
size_t _bufferSize;
BufferSet<Scalar> _bufferSet;
Buffer<Scalar> _temp;
size_t _samplesLeft;
};
}
#endif // __SDR_BUFFERNODE_HH__
sdr::Config
A collection of configuration information that is send by a source to all connected sinks to properga...
Definition: node.hh:35
sdr::BufferNode::process
virtual void process(const Buffer< Scalar > &buffer, bool allow_overwrite)
Process the incomming data.
Definition: buffernode.hh:61
sdr::Source::send
virtual void send(const RawBuffer &buffer, bool allow_overwrite=false)
Sends the given buffer to all connected sinks.
Definition: node.cc:67
sdr::BufferNode::BufferNode
BufferNode(size_t bufferSize)
Constructs a new buffer node.
Definition: buffernode.hh:23
sdr::Sink
Typed sink.
Definition: node.hh:192
sdr
Definition: autocast.hh:8
sdr::Config::numBuffers
size_t numBuffers() const
Returns the max.
Definition: node.hh:89
sdr::Source
Generic source class.
Definition: node.hh:213
sdr::BufferNode::_bufferSize
size_t _bufferSize
The desired buffer size.
Definition: buffernode.hh:95
sdr::Buffer::size
size_t size() const
Returns the number of elements of type T in this buffer.
Definition: buffer.hh:166
sdr::BufferSet
A set of buffers, that tracks their usage.
Definition: buffer.hh:288
sdr::BufferNode
A simple buffering node, that ensures a fixed buffer size.
Definition: buffernode.hh:18
sdr::RawBuffer::data
char * data() const
Returns the pointer to the data of the buffer view.
Definition: buffer.hh:69
sdr::BufferNode::_samplesLeft
size_t _samplesLeft
Number of samples left.
Definition: buffernode.hh:101
sdr::Source::setConfig
virtual void setConfig(const Config &config)
Stores the configuration and propergates it if the configuration has been changed.
Definition: node.cc:98
sdr::BufferNode::_temp
Buffer< Scalar > _temp
An intermediate buffer to hold left-over samples from the previous buffers.
Definition: buffernode.hh:99
sdr::Config::type
Type type() const
Returns the type.
Definition: node.hh:71
sdr::ConfigError
The configuration error class.
Definition: exception.hh:24
sdr::LogMessage
A log message.
Definition: logger.hh:22
sdr::Config::bufferSize
size_t bufferSize() const
Returns the max.
Definition: node.hh:83
sdr::BufferNode::_bufferSet
BufferSet< Scalar > _bufferSet
A set of output buffers.
Definition: buffernode.hh:97
sdr::Buffer< Scalar >
sdr::BufferNode::config
virtual void config(const Config &src_cfg)
Configures the buffer node.
Definition: buffernode.hh:30
sdr::Config::sampleRate
double sampleRate() const
Returns the sample rate.
Definition: node.hh:77