utils.hh
#ifndef __SDR_UTILS_HH__
#define __SDR_UTILS_HH__
#include "config.hh"
#include "node.hh"
#include "traits.hh"
#include "operators.hh"
#include "logger.hh"
#include <ctime>
namespace sdr {
template <class Scalar>
class RealImagPart: public Sink< std::complex<Scalar> >, public Source
{
public:
RealImagPart(bool select_real, double scale=1.0)
: Sink< std::complex<Scalar> >(), Source(), _buffer(), _select_real(select_real), _scale(scale)
{
// pass...
}
virtual void config(const Config &src_cfg) {
// Needs full config
if ((Config::Type_UNDEFINED==src_cfg.type()) || (0 == src_cfg.bufferSize())) { return; }
// Assert complex type
if (src_cfg.type() != Config::typeId< std::complex<Scalar> >()) {
ConfigError err;
err << "Can not configure sink of RealPart: Invalid buffer type " << src_cfg.type()
<< " expected " << Config::typeId< std::complex<Scalar> >();
throw err;
}
// Resize buffer
_buffer = Buffer<Scalar>(src_cfg.bufferSize());
// propergate config
this->setConfig(Config(Config::typeId< Scalar >(), src_cfg.sampleRate(),
src_cfg.bufferSize(), 1));
if (_select_real) {
LogMessage msg(LOG_DEBUG);
msg << "Configured RealPart node:" << std::endl
<< " type: " << Config::typeId<Scalar>() << std::endl
<< " sample-rate: " << src_cfg.sampleRate() << std::endl
<< " buffer-size: " << src_cfg.bufferSize();
Logger::get().log(msg);
}
}
virtual void process(const Buffer<std::complex<Scalar> > &buffer, bool allow_overwrite) {
// Convert
if (_select_real) {
for (size_t i=0; i<buffer.size(); i++) {
_buffer[i] = _scale*buffer[i].real();
}
} else {
for (size_t i=0; i<buffer.size(); i++) {
_buffer[i] = _scale*buffer[i].imag();
}
}
this->send(_buffer);
}
protected:
Buffer<Scalar> _buffer;
bool _select_real;
double _scale;
};
template <class Scalar>
class RealPart: public RealImagPart<Scalar>
{
public:
RealPart(double scale=1.0)
: RealImagPart<Scalar>(true, scale)
{
// pass...
}
};
template <class Scalar>
class ImagPart: public RealImagPart<Scalar>
{
public:
ImagPart(double scale=1.0)
: RealImagPart<Scalar>(false, scale)
{
// pass...
}
};
template <class Scalar>
class IQBalance: public Sink< std::complex<Scalar> >, public Source
{
public:
typedef typename Traits<Scalar>::SScalar SScalar;
public:
IQBalance(double balance=0.0)
: Sink< std::complex<Scalar> >(), Source(), _realFact(1), _imagFact(1)
{
if (balance < 0) {
// scale real part
balance = std::min(1.,-balance);
_realFact = (1-balance)*(1<<8);
_imagFact = (1<<8);
} else { // scale imag part
balance = std::min(1., balance);
_realFact = (1<<8);
_imagFact = (1-balance)*(1<<8);
}
}
virtual ~IQBalance() {
_buffer.unref();
}
double balance() const {
if (_realFact != (1<<8)) {
return (double(_realFact)/(1<<8)-1);
}
return (1-double(_imagFact)/(1<<8));
}
void setBalance(double balance) {
if (balance < 0) {
// scale real part
balance = std::min(1.,-balance);
_realFact = balance*(1<<8);
_imagFact = (1<<8);
} else { // scale imag part
balance = std::min(1., balance);
_realFact = (1<<8);
_imagFact = balance*(1<<8);
}
}
virtual void config(const Config &src_cfg) {
// Check if config is complete
if (! src_cfg.hasBufferSize()) { return; }
// Allocate buffer
_buffer = Buffer< std::complex<Scalar> >(src_cfg.bufferSize());
// Forward config
Config cfg(src_cfg); cfg.setNumBuffers(1);
this->setConfig(cfg);
}
virtual void process(const Buffer<std::complex<Scalar> > &buffer, bool allow_overwrite) {
if (allow_overwrite) {
_process(buffer, buffer);
this->send(buffer);
} else {
_process(buffer, _buffer);
this->send(_buffer.head(buffer.size()));
}
}
protected:
void _process(const Buffer< std::complex<Scalar> > &in, const Buffer< std::complex<Scalar> > &out) {
for (size_t i=0; i<in.size(); i++) {
out[i] = std::complex<Scalar>((_realFact*SScalar(in[i].real()))/(1<<8),
(_imagFact*SScalar(in[i].imag()))/(1<<8));
}
}
protected:
int32_t _realFact;
int32_t _imagFact;
Buffer< std::complex<Scalar> > _buffer;
};
template <class iScalar, class oScalar=iScalar>
class ToComplex: public Sink<iScalar>, public Source
{
public:
ToComplex(double scale=1.0)
: Sink<iScalar>(), Source(), _scale(scale)
{
// pass...
}
virtual void config(const Config &src_cfg) {
// Requires at least type & buffer size
if (!src_cfg.hasType() || !src_cfg.hasBufferSize()) { return; }
// Check input type
if (Config::typeId<iScalar>() != src_cfg.type()) {
ConfigError err;
err << "Can not configure ToComplex node: Invalid buffer type " << src_cfg.type()
<< ", expected " << Config::typeId<iScalar>();
throw err;
}
// Allocate buffer:
_buffer = Buffer< std::complex<oScalar> >(src_cfg.bufferSize());
// Propergate config
this->setConfig(
Config(Config::typeId< std::complex<oScalar> >(),
src_cfg.sampleRate(), src_cfg.bufferSize(), src_cfg.numBuffers()));
}
virtual void process(const Buffer<iScalar> &buffer, bool allow_overwrite) {
if (1.0 == _scale) {
for (size_t i=0; i<buffer.size(); i++) {
_buffer[i] = std::complex<oScalar>(oScalar(buffer[i]));
}
} else {
for (size_t i=0; i<buffer.size(); i++) {
_buffer[i] = std::complex<oScalar>(_scale*oScalar(buffer[i]));
}
}
// propergate buffer
this->send(_buffer.head(buffer.size()));
}
protected:
double _scale;
Buffer< std::complex<oScalar> > _buffer;
};
template <class iScalar, class oScalar>
class Cast : public Sink<iScalar>, public Source
{
public:
typedef typename Traits<iScalar>::SScalar iSScalar;
typedef typename Traits<oScalar>::SScalar oSScalar;
public:
Cast(oScalar scale=1, iScalar shift=0)
: Sink<iScalar>(), Source(), _can_overwrite(false), _do_scale(false),
_scale(scale), _shift(shift), _buffer()
{
// pass...
}
virtual void config(const Config &src_cfg) {
// only check type
if (!src_cfg.hasType()) { return; }
if (src_cfg.type() != Config::typeId<iScalar>()) {
ConfigError err;
err << "Can not configure Cast: Invalid input type " << src_cfg.type()
<< ", expected " << Config::typeId<iScalar>();
throw err;
}
// unreference buffer if non-empty
if (! _buffer.isEmpty()) { _buffer.unref(); }
// allocate buffer
_buffer = Buffer<oScalar>(src_cfg.bufferSize());
LogMessage msg(LOG_DEBUG);
msg << "Configure Cast node:" << std::endl
<< " conversion: "<< Config::typeId<iScalar>()
<< " -> " << Config::typeId<oScalar>() << std::endl
<< " in-place " << (_can_overwrite ? "true" : "false") << std::endl
<< " scale: " << _scale;
Logger::get().log(msg);
_can_overwrite = sizeof(iScalar) >= sizeof(oScalar);
_do_scale = (_scale != oScalar(0));
// forward config
this->setConfig(Config(Config::typeId<oScalar>(), src_cfg.sampleRate(),
src_cfg.bufferSize(), 1));
}
virtual void process(const Buffer<iScalar> &buffer, bool allow_overwrite) {
if (allow_overwrite && _can_overwrite) {
_process(buffer, Buffer<oScalar>(buffer));
} else if (_buffer.isUnused()) {
_process(buffer, _buffer);
} else {
#ifdef SDR_DEBUG
std::cerr << "Cast: Drop buffer: Output buffer is still in use by "
<< _buffer.refCount() << std::endl;
#endif
}
}
inline double scale() const { return _scale; }
void setScale(double scale) {
_scale = scale;
_do_scale = (0 != _scale);
}
protected:
inline void _process(const Buffer<iScalar> &in, const Buffer<oScalar> &out) {
if (_do_scale) {
for (size_t i=0; i<in.size(); i++) {
out[i] = _scale*( cast<iScalar,oScalar>(in[i]) + cast<iScalar, oScalar>(_shift) );
}
} else {
for (size_t i=0; i<in.size(); i++) {
out[i] = in[i]+_shift;
}
}
this->send(out.head(in.size()));
}
protected:
bool _can_overwrite;
bool _do_scale;
oScalar _scale;
iScalar _shift;
Buffer<oScalar> _buffer;
};
class UnsignedToSigned: public SinkBase, public Source
{
public:
UnsignedToSigned(float scale=1.0);
virtual ~UnsignedToSigned();
virtual void config(const Config &src_cfg);
virtual void handleBuffer(const RawBuffer &buffer, bool allow_overwrite);
protected:
void _process_int8(const RawBuffer &in, const RawBuffer &out);
void _process_int16(const RawBuffer &in, const RawBuffer &out);
protected:
void (UnsignedToSigned::*_process)(const RawBuffer &in, const RawBuffer &out);
RawBuffer _buffer;
float _scale;
};
class SignedToUnsigned: public SinkBase, public Source
{
public:
SignedToUnsigned();
virtual ~SignedToUnsigned();
virtual void config(const Config &src_cfg);
virtual void handleBuffer(const RawBuffer &buffer, bool allow_overwrite);
protected:
void _process_int8(const RawBuffer &in, const RawBuffer &out);
void _process_int16(const RawBuffer &in, const RawBuffer &out);
protected:
void (SignedToUnsigned::*_process)(const RawBuffer &in, const RawBuffer &out);
RawBuffer _buffer;
};
template <class Scalar>
class FreqShift: public Sink< std::complex<Scalar> >, public Source
{
public:
FreqShift(double shift, Scalar scale=1.0)
: Sink< std::complex<Scalar> >(), Source(),
_shift(shift), _scale(scale), _factor(1), _sample_rate(0), _delta(1)
{
// pass...
}
virtual ~FreqShift() {
// pass...
}
inline double shift() const { return _shift; }
void setShift(double shift) {
// Update delta
_shift = shift;
_delta = exp(std::complex<double>(0,2*M_PI*_shift/_sample_rate));
}
virtual void config(const Config &src_cfg) {
// Requires type, samplerate & buffersize
if ((Config::Type_UNDEFINED==src_cfg.type()) || (0==src_cfg.sampleRate()) || (0==src_cfg.bufferSize())) { return; }
// Assert type
if (src_cfg.type() != Config::typeId< std::complex<Scalar> >()) {
ConfigError err;
err << "Can not configure FreqShift node: Invalid source type " << src_cfg.type()
<< ", expected " << Config::typeId< std::complex<Scalar> >();
throw err;
}
// Allocate buffer
_buffer = Buffer< std::complex<Scalar> >(src_cfg.bufferSize());
// Store sample rate
_sample_rate = src_cfg.sampleRate();
// Precalc delta
_delta = exp(std::complex<double>(0,2*M_PI*_shift/_sample_rate));
// reset factor
_factor = 1;
LogMessage msg(LOG_DEBUG);
msg << "Configure FreqShift node:" << std::endl
<< " shift: " << _shift << std::endl
<< " scale: " << _scale << std::endl
<< " sample-rate: " << src_cfg.sampleRate() << std::endl
<< " buffer-suize: " << src_cfg.bufferSize();
Logger::get().log(msg);
// Propergate config
this->setConfig(Config(Config::typeId< std::complex<Scalar> >(), src_cfg.sampleRate(),
src_cfg.bufferSize(), 1));
}
virtual void process(const Buffer<std::complex<Scalar> > &buffer, bool allow_overwrite) {
// Shift freq:
for (size_t i=0; i<buffer.size(); i++) {
_buffer[i] = (double(_scale)*_factor)*buffer[i]; _factor *= _delta;
}
// Send buffer
this->send(_buffer);
}
protected:
Buffer< std::complex<Scalar> > _buffer;
double _shift;
Scalar _scale;
std::complex<double> _factor;
double _sample_rate;
std::complex<double> _delta;
};
template<class Scalar>
class StreamSource: public Source
{
public:
StreamSource(std::istream &stream, double sample_rate=1, size_t buffersize=1024)
: Source(), _stream(stream), _buffer(buffersize)
{
// Assemble config for stream:
this->_config = Config(Config::typeId<Scalar>(), sample_rate, buffersize, 1);
}
void next() {
if(_stream.eof()) { Queue::get().stop(); return; }
int len = _stream.read(_buffer.ptr(), _buffer.storageSize());
if (len > 0) {
this->send(_buffer.head(len/sizeof(Scalar)));
}
}
protected:
std::istream &_stream;
Buffer<Scalar> _buffer;
};
template <class Scalar>
class StreamSink: public Sink<Scalar>
{
public:
StreamSink(std::ostream &stream)
: Sink<Scalar>(), _stream(stream)
{
// pass...
}
virtual void config(const Config &src_cfg) {
if (Config::Type_UNDEFINED == src_cfg.type()) { return; }
if (src_cfg.type() != Config::typeId<Scalar>()) {
ConfigError err;
err << "Can not configure StreamSink: Invalid buffer type " << src_cfg.type()
<< ", expected " << Config::typeId<Scalar>();
throw err;
}
// done...
}
virtual void process(const Buffer<Scalar> &buffer, bool allow_overwrite) {
_stream.write(buffer.data(), buffer.size()*sizeof(Scalar));
}
protected:
std::ostream &_stream;
};
template <class Scalar>
class Scale : public Sink<Scalar>, public Source
{
public:
Scale(float scale=1, Scalar shift=0)
: Sink<Scalar>(), Source(), _scale(scale), _shift(shift)
{
// pass...
}
virtual ~Scale() {
// pass...
}
virtual void config(const Config &src_cfg) {
// Check for type & buffer size
if (!src_cfg.hasType() || !src_cfg.bufferSize()) { return; }
// Check type
if (Config::typeId<Scalar>() != src_cfg.type()) {
ConfigError err;
err << "Can not configure Scale node: Invalid type " << src_cfg.type()
<< ", expected " << Config::typeId<Scalar>();
throw err;
}
// Allocate buffer
_buffer = Buffer<Scalar>(src_cfg.bufferSize());
// Done, propergate config
this->setConfig(src_cfg);
}
virtual void process(const Buffer<Scalar> &buffer, bool allow_overwrite) {
if ((1 == _scale) && (Scalar(0) == _shift)) {
this->send(buffer, allow_overwrite);
} else if (allow_overwrite) {
// Scale inplace
for (size_t i=0; i<buffer.size(); i++) { buffer[i] *= _scale; }
this->send(buffer, allow_overwrite);
} else if (_buffer.isUnused()) {
// Scale out-of-place
for (size_t i=0; i<buffer.size(); i++) { _buffer[i] = _scale*_buffer[i]; }
this->send(_buffer.head(buffer.size()), true);
}
// else if buffer is still in use -> drop buffer...
}
protected:
Buffer<Scalar> _buffer;
float _scale;
Scalar _shift;
};
template <class Scalar>
class AGC: public Sink<Scalar>, public Source
{
public:
AGC(double tau=0.1, double target=0)
: Sink<Scalar>(), Source(), _enabled(true), _tau(tau), _lambda(0), _sd(0),
_target(target), _gain(1), _sample_rate(0)
{
if (0 == target) {
// Determine target by scalar type
switch (Config::typeId<Scalar>()) {
case Config::Type_u8:
case Config::Type_s8:
case Config::Type_cu8:
case Config::Type_cs8:
_target = 64; break;
case Config::Type_u16:
case Config::Type_s16:
case Config::Type_cu16:
case Config::Type_cs16:
_target = 16000; break;
case Config::Type_f32:
case Config::Type_f64:
case Config::Type_cf32:
case Config::Type_cf64:
_target = 0.5; break;
case Config::Type_UNDEFINED: {
ConfigError err; err << "Can not configure AGC node: Unsupported type."; throw err;
}
}
}
_sd = _target;
}
inline bool enabled() const {
return _enabled;
}
inline void enable(bool enabled) {
_enabled = enabled;
}
inline float gain() const {
return _gain;
}
inline void setGain(float gain) {
_gain = gain;
}
inline double tau() const {
return _tau;
}
inline void setTau(double tau) {
// calc decay factor
_tau = tau;
_lambda = exp(-1./(_tau*_sample_rate));
}
virtual void config(const Config &src_cfg) {
// Need sample rate & type
if (!src_cfg.hasType() || !src_cfg.hasSampleRate() || !src_cfg.hasBufferSize()) { return; }
if (Config::typeId<Scalar>() != src_cfg.type()) {
ConfigError err;
err << "Can not configure AGC node: Invalid type " << src_cfg.type()
<< ", expected " << Config::typeId<Scalar>();
throw err;
}
// calc decay factor
_sample_rate = src_cfg.sampleRate();
_lambda = exp(-1./(_tau*src_cfg.sampleRate()));
// reset variance
_sd = _target;
// Allocate buffer
_buffer = Buffer<Scalar>(src_cfg.bufferSize());
LogMessage msg(LOG_DEBUG);
msg << "Configured AGC:" << std::endl
<< " type: " << src_cfg.type() << std::endl
<< " sample-rate: " << src_cfg.sampleRate() << std::endl
<< " tau: " << _tau << std::endl
<< " lambda [1/s]: " << pow(_lambda, src_cfg.sampleRate()) << std::endl
<< " lambda [1/sam]: " << _lambda << std::endl
<< " target value: " << _target;
Logger::get().log(msg);
// Propergate config
this->setConfig(Config(Config::typeId<Scalar>(), src_cfg.sampleRate(),
src_cfg.bufferSize(), 1));
}
virtual void process(const Buffer<Scalar> &buffer, bool allow_overwrite) {
// Simply forward buffer if disabled
if ((! _enabled) && (0 == _gain) ) {
this->send(buffer, allow_overwrite); return;
}
// Update signal ampl
for (size_t i=0; i<buffer.size(); i++) {
_sd = _lambda*_sd + (1-_lambda)*std::abs(buffer[i]);
if (_enabled) { _gain = _target/(4*_sd); }
_buffer[i] = _gain*buffer[i];
}
this->send(_buffer);
}
protected:
bool _enabled;
float _tau;
float _lambda;
float _sd;
float _target;
float _gain;
double _sample_rate;
Buffer<Scalar> _buffer;
};
template <class Scalar>
class DebugStore: public Sink<Scalar>
{
public:
DebugStore() : Sink<Scalar>(), _buffer(), _view() { }
virtual ~DebugStore() {
_buffer.unref();
}
virtual void config(const Config &src_cfg) {
// Requires type and buffer size
if (!src_cfg.hasType() || !src_cfg.hasBufferSize()) { return; }
// Check type
if (Config::typeId<Scalar>() != src_cfg.type()) {
ConfigError err;
err << "Can not configure DebugStore node: Invalid input type " << src_cfg.type()
<< ", expected " << Config::typeId<Scalar>();
throw err;
}
// Allocate buffer
_buffer = Buffer<Scalar>(src_cfg.bufferSize());
}
virtual void process(const Buffer<Scalar> &buffer, bool allow_overwrite) {
size_t N = std::min(buffer.size(), _buffer.size());
memcpy(_buffer.ptr(), buffer.data(), N*sizeof(Scalar));
// Store view
_view = _buffer.head(N);
}
inline const Buffer<Scalar> &buffer() const { return _view; }
inline void clear() { _view = Buffer<Scalar>(); }
public:
Buffer<Scalar> _buffer;
Buffer<Scalar> _view;
};
template <class Scalar>
class DebugDump: public Sink<Scalar>
{
public:
DebugDump(std::ostream &stream=std::cerr)
: Sink<Scalar>(), _stream(stream)
{
// pass...
}
virtual ~DebugDump() {
// pass...
}
virtual void config(const Config &src_cfg) {
// Requires type
if (!src_cfg.hasType()) { return; }
// check type
if (Config::typeId<Scalar>() != src_cfg.type()) {
ConfigError err;
err << "Can not configure DebugDump sink: Invalid input type " << src_cfg.type()
<< ", expected " << Config::typeId<Scalar>();
throw err;
}
// Done...
}
virtual void process(const Buffer<Scalar> &buffer, bool allow_overwrite) {
_stream << buffer << std::endl;
}
protected:
std::ostream &_stream;
};
class TextDump : public Sink<uint8_t>
{
public:
TextDump(std::ostream &stream=std::cerr);
virtual void config(const Config &src_cfg);
virtual void process(const Buffer<uint8_t> &buffer, bool allow_overwrite);
protected:
std::ostream &_stream;
};
template <class Scalar>
class GWNSource: public Source
{
public:
GWNSource(double sample_rate, size_t buffer_size=1024)
: Source(), _sample_rate(sample_rate), _buffer_size(buffer_size), _buffer(_buffer_size),
_mean(0)
{
// Seed RNG
std::srand(std::time(0));
// Determine mean
switch (Config::typeId<Scalar>()) {
case Config::Type_u8:
case Config::Type_cu8:
case Config::Type_u16:
case Config::Type_cu16:
_mean = 1;
break;
default:
_mean = 0;
break;
}
// Propergate config
setConfig(Config(Config::typeId<Scalar>(), _sample_rate, _buffer_size, 1));
}
virtual ~GWNSource() {
_buffer.unref();
}
void next() {
double a,b;
for (size_t i=0; i<_buffer_size; i+=2) {
_getNormal(a,b);
_buffer[i] = Scalar(Traits<Scalar>::scale*(a+_mean));
_buffer[i+1] = Scalar(Traits<Scalar>::scale*(b+_mean));
}
if (_buffer_size%2) {
_getNormal(a,b); _buffer[_buffer_size-1] = Scalar(Traits<Scalar>::scale*(a+_mean));
}
this->send(_buffer, true);
}
protected:
void _getNormal(double &a, double &b) {
// Obtain pair of std. normal floating point values
double x = 2*(double(std::rand())/RAND_MAX) - 1;
double y = 2*(double(std::rand())/RAND_MAX) - 1;
double s = std::sqrt(x*x + y*y);
while (s >= 1) {
x = 2*(double(std::rand())/RAND_MAX) - 1;
y = 2*(double(std::rand())/RAND_MAX) - 1;
s = std::sqrt(x*x + y*y);
}
a = x*std::sqrt(-2*log(s)/s);
b = y*std::sqrt(-2*log(s)/s);
}
protected:
double _sample_rate;
size_t _buffer_size;
Buffer<Scalar> _buffer;
double _mean;
};
}
#endif // __SDR_UTILS_HH__
sdr::AGC::enable
void enable(bool enabled)
Enable/disable the AGC node.
Definition: utils.hh:698
sdr::ToComplex::process
virtual void process(const Buffer< iScalar > &buffer, bool allow_overwrite)
Casts the input real buffer into the complex output buffer.
Definition: utils.hh:241
sdr::DebugStore::_buffer
Buffer< Scalar > _buffer
A pre-allocated buffer, that will hold the last data received.
Definition: utils.hh:838
sdr::UnsignedToSigned::_process_int16
void _process_int16(const RawBuffer &in, const RawBuffer &out)
Performs the cast for uint16 -> int16.
Definition: utils.cc:91
sdr::Config
A collection of configuration information that is send by a source to all connected sinks to properga...
Definition: node.hh:35
sdr::GWNSource::_sample_rate
double _sample_rate
The sample rate.
Definition: utils.hh:973
sdr::AGC::setGain
void setGain(float gain)
Resets the current gain factor.
Definition: utils.hh:708
sdr::UnsignedToSigned::_buffer
RawBuffer _buffer
The output buffer, unused if the cast can be performed in-place.
Definition: utils.hh:395
sdr::Config::Type_cf32
Complex (aka I/Q) type of 32bit floats aka. std::complex<float>.
Definition: node.hh:51
sdr::Cast::_scale
oScalar _scale
The scaling.
Definition: utils.hh:361
sdr::DebugDump::process
virtual void process(const Buffer< Scalar > &buffer, bool allow_overwrite)
Dumps the received buffer.
Definition: utils.hh:877
sdr::AGC::gain
float gain() const
Returns the current gain factor.
Definition: utils.hh:703
sdr::SignedToUnsigned::config
virtual void config(const Config &src_cfg)
Configures the cast node.
Definition: utils.cc:117
sdr::AGC::_tau
float _tau
The time-constant of the AGC.
Definition: utils.hh:780
sdr::RawBuffer
Base class of all buffers, represents an untyped array of bytes.
Definition: buffer.hh:32
sdr::RealImagPart::_scale
double _scale
The scale.
Definition: utils.hh:76
sdr::FreqShift::setShift
void setShift(double shift)
Sets the frequency shift.
Definition: utils.hh:457
sdr::Source::_config
Config _config
Holds the source configuration, this can be updated by calling setConfig.
Definition: node.hh:253
sdr::SignedToUnsigned::_process
void(SignedToUnsigned::* _process)(const RawBuffer &in, const RawBuffer &out)
Type-cast callback.
Definition: utils.hh:425
sdr::AGC::process
virtual void process(const Buffer< Scalar > &buffer, bool allow_overwrite)
Performs the amplification and adjusts the gain.
Definition: utils.hh:761
sdr::SignedToUnsigned::handleBuffer
virtual void handleBuffer(const RawBuffer &buffer, bool allow_overwrite)
Performs the cast.
Definition: utils.cc:158
sdr::FreqShift::_scale
Scalar _scale
The optional scale.
Definition: utils.hh:512
sdr::Cast::scale
double scale() const
Returns the scaling.
Definition: utils.hh:332
sdr::Cast::Cast
Cast(oScalar scale=1, iScalar shift=0)
Constructs a type-cast with optional scaleing.
Definition: utils.hh:277
sdr::Scale::~Scale
virtual ~Scale()
Destructor.
Definition: utils.hh:607
sdr::ToComplex::_buffer
Buffer< std::complex< oScalar > > _buffer
The output buffer.
Definition: utils.hh:259
sdr::Config::Type_s16
Real signed 16b ints.
Definition: node.hh:44
sdr::SignedToUnsigned::~SignedToUnsigned
virtual ~SignedToUnsigned()
Destructor.
Definition: utils.cc:112
sdr::UnsignedToSigned
Performs a reinterprete cast from an unsinged value to a singed one.
Definition: utils.hh:372
sdr::GWNSource
A Gaussian White Noise source.
Definition: utils.hh:907
sdr::TextDump::_stream
std::ostream & _stream
The output stream.
Definition: utils.hh:900
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::DebugStore::buffer
const Buffer< Scalar > & buffer() const
Retunrs a reference to the last received buffer.
Definition: utils.hh:832
sdr::Queue::get
static Queue & get()
Get a reference to the global instance of the queue.
Definition: queue.cc:15
sdr::DebugStore::DebugStore
DebugStore()
Constrctor.
Definition: utils.hh:803
sdr::StreamSink::config
virtual void config(const Config &src_cfg)
Configures the raw sink.
Definition: utils.hh:568
sdr::UnsignedToSigned::config
virtual void config(const Config &src_cfg)
Configures the cast node.
Definition: utils.cc:20
sdr::Sink
Typed sink.
Definition: node.hh:192
sdr::RealImagPart
Extracts the real or imaginary part of a complex valued data stream.
Definition: utils.hh:17
sdr::Scale::Scale
Scale(float scale=1, Scalar shift=0)
Constructs the scaling node.
Definition: utils.hh:600
sdr::FreqShift::_shift
double _shift
The frequency shift in Hz ( ).
Definition: utils.hh:510
sdr::AGC::_sample_rate
double _sample_rate
The current sample-rate.
Definition: utils.hh:790
sdr::Config::Type_cu16
Complex (aka I/Q) type of unsigned 16b ints.
Definition: node.hh:49
sdr::IQBalance::setBalance
void setBalance(double balance)
Sets the I/Q balance.
Definition: utils.hh:153
sdr
Definition: autocast.hh:8
sdr::Config::numBuffers
size_t numBuffers() const
Returns the max.
Definition: node.hh:89
sdr::RawBuffer::isEmpty
bool isEmpty() const
Returns true if the buffer is invalid/empty.
Definition: buffer.hh:77
sdr::Config::Type_s8
Real signed 8b ints.
Definition: node.hh:42
std
Definition: operators.hh:9
sdr::StreamSource::StreamSource
StreamSource(std::istream &stream, double sample_rate=1, size_t buffersize=1024)
Constructs a raw input source.
Definition: utils.hh:529
sdr::RawBuffer::storageSize
size_t storageSize() const
Returns the raw buffer size in bytes.
Definition: buffer.hh:75
sdr::FreqShift
Performs a frequency shift on a complex input signal, by multiplying it with .
Definition: utils.hh:437
sdr::ToComplex::ToComplex
ToComplex(double scale=1.0)
Constructor.
Definition: utils.hh:215
sdr::Queue::stop
void stop()
Signals the queue to stop processing.
Definition: queue.cc:64
sdr::Config::hasSampleRate
bool hasSampleRate() const
If true, the configuration has a sample rate.
Definition: node.hh:75
sdr::Source
Generic source class.
Definition: node.hh:213
sdr::Config::Type_u8
Real unsigned 8b ints.
Definition: node.hh:41
sdr::RawBuffer::refCount
int refCount() const
Returns the reference counter.
Definition: buffer.hh:84
sdr::Cast
Explicit type cast node.
Definition: utils.hh:267
sdr::SignedToUnsigned::SignedToUnsigned
SignedToUnsigned()
Constructor with optional scaleing.
Definition: utils.cc:106
sdr::DebugStore::config
virtual void config(const Config &src_cfg)
Configures the node.
Definition: utils.hh:809
sdr::Cast::iSScalar
Traits< iScalar >::SScalar iSScalar
Specifies the input super scalar.
Definition: utils.hh:271
sdr::AGC::_buffer
Buffer< Scalar > _buffer
The output buffer.
Definition: utils.hh:792
sdr::DebugStore::process
virtual void process(const Buffer< Scalar > &buffer, bool allow_overwrite)
Stores the given buffer.
Definition: utils.hh:824
sdr::Cast::process
virtual void process(const Buffer< iScalar > &buffer, bool allow_overwrite)
Performs the type-cast node.
Definition: utils.hh:318
sdr::FreqShift::process
virtual void process(const Buffer< std::complex< Scalar > > &buffer, bool allow_overwrite)
Performs the frequency shift.
Definition: utils.hh:497
sdr::Buffer::size
size_t size() const
Returns the number of elements of type T in this buffer.
Definition: buffer.hh:166
sdr::Config::hasType
bool hasType() const
If true, the configuration has a type.
Definition: node.hh:69
sdr::IQBalance::_imagFact
int32_t _imagFact
Scaleing factor for the imaginary part.
Definition: utils.hh:201
sdr::FreqShift::FreqShift
FreqShift(double shift, Scalar scale=1.0)
Constructs a frequency shift node with optional scaleing of the result.
Definition: utils.hh:441
sdr::StreamSink::_stream
std::ostream & _stream
The output stream.
Definition: utils.hh:587
sdr::Cast::setScale
void setScale(double scale)
Sets the scaling.
Definition: utils.hh:335
sdr::DebugDump::~DebugDump
virtual ~DebugDump()
Destructor.
Definition: utils.hh:858
sdr::Config::Type_f64
Real 64b floats aka. "double".
Definition: node.hh:46
sdr::TextDump
Dumps the received uin8_t byte-stream as (ASCII) text.
Definition: utils.hh:888
sdr::RawBuffer::data
char * data() const
Returns the pointer to the data of the buffer view.
Definition: buffer.hh:69
sdr::Config::Type_u16
Real unsigned 16b ints.
Definition: node.hh:43
sdr::GWNSource::_buffer_size
size_t _buffer_size
The size of the buffer.
Definition: utils.hh:975
sdr::AGC::AGC
AGC(double tau=0.1, double target=0)
Constructor.
Definition: utils.hh:662
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::ToComplex::config
virtual void config(const Config &src_cfg)
Configures the node.
Definition: utils.hh:222
sdr::Buffer::head
Buffer< T > head(size_t n) const
Returns a new view on this buffer.
Definition: buffer.hh:237
sdr::ToComplex::_scale
double _scale
The scale.
Definition: utils.hh:257
sdr::SignedToUnsigned::_process_int16
void _process_int16(const RawBuffer &in, const RawBuffer &out)
Performs the int16 -> uint16 cast.
Definition: utils.cc:181
sdr::GWNSource::_buffer
Buffer< Scalar > _buffer
The output buffer.
Definition: utils.hh:977
sdr::GWNSource::GWNSource
GWNSource(double sample_rate, size_t buffer_size=1024)
Constructor.
Definition: utils.hh:911
sdr::IQBalance::balance
double balance() const
Retunrs the balance.
Definition: utils.hh:145
sdr::AGC::tau
double tau() const
Returns the time-constant of the AGC.
Definition: utils.hh:713
sdr::AGC::_sd
float _sd
The averaged std.
Definition: utils.hh:784
sdr::RealPart
Selects the real part of a complex signal.
Definition: utils.hh:83
sdr::DebugDump::_stream
std::ostream & _stream
A reference to the output stream.
Definition: utils.hh:883
sdr::UnsignedToSigned::~UnsignedToSigned
virtual ~UnsignedToSigned()
Destructor.
Definition: utils.cc:15
sdr::RealImagPart::_buffer
Buffer< Scalar > _buffer
The output buffer.
Definition: utils.hh:72
sdr::RealImagPart::process
virtual void process(const Buffer< std::complex< Scalar > > &buffer, bool allow_overwrite)
Processes the incomming data.
Definition: utils.hh:56
sdr::StreamSink::process
virtual void process(const Buffer< Scalar > &buffer, bool allow_overwrite)
Dumps the buffer into the stream as raw data.
Definition: utils.hh:580
sdr::IQBalance::~IQBalance
virtual ~IQBalance()
Destructor.
Definition: utils.hh:140
sdr::FreqShift::_sample_rate
double _sample_rate
The current sample rate.
Definition: utils.hh:516
sdr::Logger::log
void log(const LogMessage &message)
Logs a message.
Definition: logger.cc:100
sdr::IQBalance::SScalar
Traits< Scalar >::SScalar SScalar
The internal used compute scalar.
Definition: utils.hh:117
sdr::RealImagPart::RealImagPart
RealImagPart(bool select_real, double scale=1.0)
Constructor.
Definition: utils.hh:22
sdr::GWNSource::_mean
double _mean
The mean value of the GWN.
Definition: utils.hh:979
sdr::Config::type
Type type() const
Returns the type.
Definition: node.hh:71
sdr::UnsignedToSigned::_process_int8
void _process_int8(const RawBuffer &in, const RawBuffer &out)
Performs the cast for uint8 -> int8.
Definition: utils.cc:78
sdr::ImagPart
Selects the imaginary part of a complex signal.
Definition: utils.hh:98
sdr::Scale::process
virtual void process(const Buffer< Scalar > &buffer, bool allow_overwrite)
Performs the scaleing.
Definition: utils.hh:629
sdr::DebugStore::_view
Buffer< Scalar > _view
A view to the last data received.
Definition: utils.hh:840
sdr::Cast::config
virtual void config(const Config &src_cfg)
Configures the type-cast node.
Definition: utils.hh:285
sdr::FreqShift::_buffer
Buffer< std::complex< Scalar > > _buffer
The output buffer.
Definition: utils.hh:508
sdr::DebugDump::DebugDump
DebugDump(std::ostream &stream=std::cerr)
Constructor.
Definition: utils.hh:851
sdr::UnsignedToSigned::_process
void(UnsignedToSigned::* _process)(const RawBuffer &in, const RawBuffer &out)
Type-cast callback.
Definition: utils.hh:393
sdr::SignedToUnsigned
Performs a reinterprete cast from an unsinged value to a singed one.
Definition: utils.hh:404
sdr::Scale
Simple scaling node.
Definition: utils.hh:596
sdr::Cast::_shift
iScalar _shift
Another scaling, using integer shift operation (faster).
Definition: utils.hh:363
sdr::UnsignedToSigned::_scale
float _scale
Holds the scaleing.
Definition: utils.hh:397
sdr::IQBalance
A simple node, that allows to balance an IQ signal.
Definition: utils.hh:113
sdr::IQBalance::_buffer
Buffer< std::complex< Scalar > > _buffer
The working buffer.
Definition: utils.hh:203
sdr::Config::typeId
static Type typeId()
Returns the type-id of the template type.
sdr::FreqShift::shift
double shift() const
Returns the frequency shift.
Definition: utils.hh:454
sdr::Logger::get
static Logger & get()
Returns the singleton instance of the logger.
Definition: logger.cc:89
sdr::StreamSource
Reads raw samples from an imput stream, (ie a file).
Definition: utils.hh:525
sdr::DebugDump::config
virtual void config(const Config &src_cfg)
Configures the dump-node.
Definition: utils.hh:863
sdr::Scale::_shift
Scalar _shift
Alternative formulation for the scaling, using integer shift operators.
Definition: utils.hh:650
sdr::DebugDump
Dumps buffers in a human readable form.
Definition: utils.hh:847
sdr::Config::Type_f32
Real 32b floats aka. "float".
Definition: node.hh:45
sdr::RealImagPart::_select_real
bool _select_real
Real/Imag selection.
Definition: utils.hh:74
sdr::ConfigError
The configuration error class.
Definition: exception.hh:24
sdr::TextDump::TextDump
TextDump(std::ostream &stream=std::cerr)
Constructor.
Definition: utils.cc:193
sdr::LogMessage
A log message.
Definition: logger.hh:22
sdr::Cast::oSScalar
Traits< oScalar >::SScalar oSScalar
Specified the output super scalar.
Definition: utils.hh:273
sdr::DebugStore
Keeps a copy of the last buffer received.
Definition: utils.hh:799
sdr::Config::bufferSize
size_t bufferSize() const
Returns the max.
Definition: node.hh:83
sdr::GWNSource::next
void next()
Samples and emits the next chunk of data.
Definition: utils.hh:941
sdr::Cast::_process
void _process(const Buffer< iScalar > &in, const Buffer< oScalar > &out)
Internal used method to perform the type-case out-of-place.
Definition: utils.hh:342
sdr::Scale::config
virtual void config(const Config &src_cfg)
Configures the scaleing node.
Definition: utils.hh:612
sdr::TextDump::process
virtual void process(const Buffer< uint8_t > &buffer, bool allow_overwrite)
Processes the input stream.
Definition: utils.cc:213
sdr::UnsignedToSigned::handleBuffer
virtual void handleBuffer(const RawBuffer &buffer, bool allow_overwrite)
Performs the cast.
Definition: utils.cc:64
sdr::StreamSource::_stream
std::istream & _stream
The input stream.
Definition: utils.hh:548
sdr::SinkBase
Basic interface of all Sinks.
Definition: node.hh:174
sdr::AGC::_lambda
float _lambda
One over the time-constant.
Definition: utils.hh:782
sdr::RawBuffer::ptr
char * ptr() const
Returns the pointer to the data (w/o view).
Definition: buffer.hh:67
sdr::Config::Type_cs8
Complex (aka I/Q) type of signed 8b ints.
Definition: node.hh:48
sdr::Scale::_scale
float _scale
The scaling.
Definition: utils.hh:648
sdr::StreamSource::_buffer
Buffer< Scalar > _buffer
The output buffer.
Definition: utils.hh:550
sdr::DebugStore::clear
void clear()
Clears the buffer.
Definition: utils.hh:834
sdr::AGC::setTau
void setTau(double tau)
Sets the time-constant of the AGC.
Definition: utils.hh:718
sdr::SignedToUnsigned::_process_int8
void _process_int8(const RawBuffer &in, const RawBuffer &out)
Performs the int8 -> uint8 cast.
Definition: utils.cc:172
sdr::Cast::_do_scale
bool _do_scale
If true, the output gets scaled.
Definition: utils.hh:359
sdr::IQBalance::_realFact
int32_t _realFact
Scaleing factor for the real part.
Definition: utils.hh:199
sdr::ToComplex
Tiny helper node to transform a real part into a complex, including a possible type-cast.
Definition: utils.hh:211
sdr::RealPart::RealPart
RealPart(double scale=1.0)
Constructor.
Definition: utils.hh:87
sdr::Config::Type_cs16
Complex (aka I/Q) type of signed 16b ints.
Definition: node.hh:50
sdr::Config::Type_cu8
Complex (aka I/Q) type of unsigned 8b ints.
Definition: node.hh:47
sdr::FreqShift::_factor
std::complex< double > _factor
The current exponental factor, gets updated for every sample.
Definition: utils.hh:514
sdr::RealImagPart::config
virtual void config(const Config &src_cfg)
Configures the node.
Definition: utils.hh:29
sdr::RawBuffer::unref
void unref()
Dereferences the buffer.
Definition: buffer.cc:63
sdr::RawBuffer::isUnused
bool isUnused() const
We assume here that buffers are owned by one object: A buffer is therefore "unused" if the owner hold...
Definition: buffer.hh:87
sdr::UnsignedToSigned::UnsignedToSigned
UnsignedToSigned(float scale=1.0)
Constructor with optional scaleing.
Definition: utils.cc:9
sdr::Cast::_buffer
Buffer< oScalar > _buffer
The output buffer, unused if the type-cast is performed in-place .
Definition: utils.hh:365
sdr::StreamSink::StreamSink
StreamSink(std::ostream &stream)
Constructor.
Definition: utils.hh:561
sdr::AGC::enabled
bool enabled() const
Returns true, if the AGC is enabled.
Definition: utils.hh:693
sdr::FreqShift::_delta
std::complex< double > _delta
.
Definition: utils.hh:518
sdr::TextDump::config
virtual void config(const Config &src_cfg)
Configures the sink.
Definition: utils.cc:200
sdr::AGC::_target
float _target
The target level of the output signal.
Definition: utils.hh:786
sdr::Traits
Forward declaration of type tratis template.
Definition: traits.hh:20
sdr::GWNSource::~GWNSource
virtual ~GWNSource()
Destructor.
Definition: utils.hh:934
sdr::Scale::_buffer
Buffer< Scalar > _buffer
The output buffer, unused if the scaling is performed in-place.
Definition: utils.hh:646
sdr::AGC::_gain
float _gain
The current gain factor.
Definition: utils.hh:788
sdr::SignedToUnsigned::_buffer
RawBuffer _buffer
The output buffer, unused if the cast is performed in-place.
Definition: utils.hh:427
sdr::Cast::_can_overwrite
bool _can_overwrite
If true, the type-cast (an scaleing) can be performed in-place.
Definition: utils.hh:357
sdr::IQBalance::_process
void _process(const Buffer< std::complex< Scalar > > &in, const Buffer< std::complex< Scalar > > &out)
The actual implementation.
Definition: utils.hh:190
sdr::AGC
An automatic gain control node.
Definition: utils.hh:658
sdr::StreamSource::next
void next()
Reads the next chunk.
Definition: utils.hh:538
sdr::FreqShift::config
virtual void config(const Config &src_cfg)
Configures the frequency shift node.
Definition: utils.hh:464
sdr::AGC::config
virtual void config(const Config &src_cfg)
Configures the AGC node.
Definition: utils.hh:725
sdr::StreamSink
Serializes the incomming buffers as raw data.
Definition: utils.hh:557
sdr::IQBalance::process
virtual void process(const Buffer< std::complex< Scalar > > &buffer, bool allow_overwrite)
Processes a buffer.
Definition: utils.hh:178
sdr::ImagPart::ImagPart
ImagPart(double scale=1.0)
Constructor.
Definition: utils.hh:102
sdr::Buffer< Scalar >
sdr::Config::hasBufferSize
bool hasBufferSize() const
If true, the configuration has a buffer size.
Definition: node.hh:81
sdr::FreqShift::~FreqShift
virtual ~FreqShift()
Destructor.
Definition: utils.hh:449
sdr::GWNSource::_getNormal
void _getNormal(double &a, double &b)
Sample two std.
Definition: utils.hh:957
sdr::Config::Type_cf64
Complex (aka I/Q) type of 64bit floats aka. std::complex<double>.
Definition: node.hh:52
sdr::IQBalance::config
virtual void config(const Config &src_cfg)
Configures the node.
Definition: utils.hh:167
sdr::Config::sampleRate
double sampleRate() const
Returns the sample rate.
Definition: node.hh:77
sdr::AGC::_enabled
bool _enabled
If true, the automatic gain adjustment is enabled.
Definition: utils.hh:778
sdr::IQBalance::IQBalance
IQBalance(double balance=0.0)
Constructor.
Definition: utils.hh:124