1 #ifndef __SDR_UTILS_HH__
2 #define __SDR_UTILS_HH__
7 #include "operators.hh"
16 template <
class Scalar>
31 if ((Config::Type_UNDEFINED==src_cfg.
type()) || (0 == src_cfg.
bufferSize())) {
return; }
33 if (src_cfg.
type() != Config::typeId< std::complex<Scalar> >()) {
35 err <<
"Can not configure sink of RealPart: Invalid buffer type " << src_cfg.
type()
36 <<
" expected " << Config::typeId< std::complex<Scalar> >();
47 msg <<
"Configured RealPart node:" << std::endl
48 <<
" type: " << Config::typeId<Scalar>() << std::endl
49 <<
" sample-rate: " << src_cfg.
sampleRate() << std::endl
56 virtual void process(
const Buffer<std::complex<Scalar> > &buffer,
bool allow_overwrite) {
59 for (
size_t i=0; i<buffer.size(); i++) {
63 for (
size_t i=0; i<buffer.size(); i++) {
82 template <
class Scalar>
97 template <
class Scalar>
112 template <
class Scalar>
156 balance = std::min(1.,-balance);
160 balance = std::min(1., balance);
173 Config cfg(src_cfg); cfg.setNumBuffers(1);
178 virtual void process(
const Buffer<std::complex<Scalar> > &buffer,
bool allow_overwrite) {
179 if (allow_overwrite) {
191 for (
size_t i=0; i<in.size(); i++) {
210 template <
class iScalar,
class oScalar=iScalar>
226 if (Config::typeId<iScalar>() != src_cfg.
type()) {
228 err <<
"Can not configure ToComplex node: Invalid buffer type " << src_cfg.
type()
229 <<
", expected " << Config::typeId<iScalar>();
243 for (
size_t i=0; i<buffer.
size(); i++) {
244 _buffer[i] = std::complex<oScalar>(oScalar(buffer[i]));
247 for (
size_t i=0; i<buffer.
size(); i++) {
248 _buffer[i] = std::complex<oScalar>(
_scale*oScalar(buffer[i]));
266 template <
class iScalar,
class oScalar>
287 if (!src_cfg.
hasType()) {
return; }
288 if (src_cfg.
type() != Config::typeId<iScalar>()) {
290 err <<
"Can not configure Cast: Invalid input type " << src_cfg.
type()
291 <<
", expected " << Config::typeId<iScalar>();
302 msg <<
"Configure Cast node:" << std::endl
303 <<
" conversion: "<< Config::typeId<iScalar>()
304 <<
" -> " << Config::typeId<oScalar>() << std::endl
305 <<
" in-place " << (
_can_overwrite ?
"true" :
"false") << std::endl
325 std::cerr <<
"Cast: Drop buffer: Output buffer is still in use by "
344 for (
size_t i=0; i<in.
size(); i++) {
345 out[i] =
_scale*( cast<iScalar,oScalar>(in[i]) + cast<iScalar, oScalar>(
_shift) );
348 for (
size_t i=0; i<in.
size(); i++) {
436 template <
class Scalar>
468 if (src_cfg.
type() != Config::typeId< std::complex<Scalar> >()) {
470 err <<
"Can not configure FreqShift node: Invalid source type " << src_cfg.
type()
471 <<
", expected " << Config::typeId< std::complex<Scalar> >();
479 _delta = exp(std::complex<double>(0,2*M_PI*
_shift/_sample_rate));
484 msg <<
"Configure FreqShift node:" << std::endl
485 <<
" shift: " <<
_shift << std::endl
486 <<
" scale: " <<
_scale << std::endl
487 <<
" sample-rate: " << src_cfg.
sampleRate() << std::endl
497 virtual void process(
const Buffer<std::complex<Scalar> > &buffer,
bool allow_overwrite) {
499 for (
size_t i=0; i<buffer.size(); i++) {
524 template<
class Scalar>
529 StreamSource(std::istream &stream,
double sample_rate=1,
size_t buffersize=1024)
533 this->
_config =
Config(Config::typeId<Scalar>(), sample_rate, buffersize, 1);
556 template <
class Scalar>
569 if (Config::Type_UNDEFINED == src_cfg.
type()) {
return; }
570 if (src_cfg.
type() != Config::typeId<Scalar>()) {
572 err <<
"Can not configure StreamSink: Invalid buffer type " << src_cfg.
type()
573 <<
", expected " << Config::typeId<Scalar>();
595 template <
class Scalar>
600 Scale(
float scale=1, Scalar shift=0)
616 if (Config::typeId<Scalar>() != src_cfg.
type()) {
618 err <<
"Can not configure Scale node: Invalid type " << src_cfg.
type()
619 <<
", expected " << Config::typeId<Scalar>();
631 this->
send(buffer, allow_overwrite);
632 }
else if (allow_overwrite) {
634 for (
size_t i=0; i<buffer.
size(); i++) { buffer[i] *=
_scale; }
635 this->
send(buffer, allow_overwrite);
657 template <
class Scalar>
668 switch (Config::typeId<Scalar>()) {
684 case Config::Type_UNDEFINED: {
685 ConfigError err; err <<
"Can not configure AGC node: Unsupported type.";
throw err;
713 inline double tau()
const {
728 if (Config::typeId<Scalar>() != src_cfg.
type()) {
730 err <<
"Can not configure AGC node: Invalid type " << src_cfg.
type()
731 <<
", expected " << Config::typeId<Scalar>();
745 msg <<
"Configured AGC:" << std::endl
746 <<
" type: " << src_cfg.
type() << std::endl
747 <<
" sample-rate: " << src_cfg.
sampleRate() << std::endl
748 <<
" tau: " <<
_tau << std::endl
750 <<
" lambda [1/sam]: " <<
_lambda << std::endl
751 <<
" target value: " <<
_target;
764 this->
send(buffer, allow_overwrite);
return;
767 for (
size_t i=0; i<buffer.
size(); i++) {
798 template <
class Scalar>
813 if (Config::typeId<Scalar>() != src_cfg.
type()) {
815 err <<
"Can not configure DebugStore node: Invalid input type " << src_cfg.
type()
816 <<
", expected " << Config::typeId<Scalar>();
846 template <
class Scalar>
865 if (!src_cfg.
hasType()) {
return; }
867 if (Config::typeId<Scalar>() != src_cfg.
type()) {
869 err <<
"Can not configure DebugDump sink: Invalid input type " << src_cfg.
type()
870 <<
", expected " << Config::typeId<Scalar>();
878 _stream << buffer << std::endl;
892 TextDump(std::ostream &stream=std::cerr);
906 template <
class Scalar>
916 std::srand(std::time(0));
918 switch (Config::typeId<Scalar>()) {
948 if (_buffer_size%2) {
959 double x = 2*(double(std::rand())/RAND_MAX) - 1;
960 double y = 2*(double(std::rand())/RAND_MAX) - 1;
961 double s = std::sqrt(x*x + y*y);
963 x = 2*(double(std::rand())/RAND_MAX) - 1;
964 y = 2*(double(std::rand())/RAND_MAX) - 1;
965 s = std::sqrt(x*x + y*y);
967 a = x*std::sqrt(-2*log(s)/s);
968 b = y*std::sqrt(-2*log(s)/s);
984 #endif // __SDR_UTILS_HH__
void enable(bool enabled)
Enable/disable the AGC node.
Definition: utils.hh:698
virtual void process(const Buffer< iScalar > &buffer, bool allow_overwrite)
Casts the input real buffer into the complex output buffer.
Definition: utils.hh:241
Buffer< Scalar > _buffer
A pre-allocated buffer, that will hold the last data received.
Definition: utils.hh:838
void _process_int16(const RawBuffer &in, const RawBuffer &out)
Performs the cast for uint16 -> int16.
Definition: utils.cc:91
A collection of configuration information that is send by a source to all connected sinks to properga...
Definition: node.hh:35
double _sample_rate
The sample rate.
Definition: utils.hh:973
void setGain(float gain)
Resets the current gain factor.
Definition: utils.hh:708
RawBuffer _buffer
The output buffer, unused if the cast can be performed in-place.
Definition: utils.hh:395
Complex (aka I/Q) type of 32bit floats aka. std::complex.
Definition: node.hh:51
oScalar _scale
The scaling.
Definition: utils.hh:361
virtual void process(const Buffer< Scalar > &buffer, bool allow_overwrite)
Dumps the received buffer.
Definition: utils.hh:877
float gain() const
Returns the current gain factor.
Definition: utils.hh:703
virtual void config(const Config &src_cfg)
Configures the cast node.
Definition: utils.cc:117
float _tau
The time-constant of the AGC.
Definition: utils.hh:780
Base class of all buffers, represents an untyped array of bytes.
Definition: buffer.hh:32
double _scale
The scale.
Definition: utils.hh:76
void setShift(double shift)
Sets the frequency shift.
Definition: utils.hh:457
Config _config
Holds the source configuration, this can be updated by calling setConfig.
Definition: node.hh:253
void(SignedToUnsigned::* _process)(const RawBuffer &in, const RawBuffer &out)
Type-cast callback.
Definition: utils.hh:425
virtual void process(const Buffer< Scalar > &buffer, bool allow_overwrite)
Performs the amplification and adjusts the gain.
Definition: utils.hh:761
virtual void handleBuffer(const RawBuffer &buffer, bool allow_overwrite)
Performs the cast.
Definition: utils.cc:158
Scalar _scale
The optional scale.
Definition: utils.hh:512
double scale() const
Returns the scaling.
Definition: utils.hh:332
Cast(oScalar scale=1, iScalar shift=0)
Constructs a type-cast with optional scaleing.
Definition: utils.hh:277
virtual ~Scale()
Destructor.
Definition: utils.hh:607
Buffer< std::complex< oScalar > > _buffer
The output buffer.
Definition: utils.hh:259
Real signed 16b ints.
Definition: node.hh:44
virtual ~SignedToUnsigned()
Destructor.
Definition: utils.cc:112
Performs a reinterprete cast from an unsinged value to a singed one.
Definition: utils.hh:372
A Gaussian White Noise source.
Definition: utils.hh:907
std::ostream & _stream
The output stream.
Definition: utils.hh:900
virtual void send(const RawBuffer &buffer, bool allow_overwrite=false)
Sends the given buffer to all connected sinks.
Definition: node.cc:67
const Buffer< Scalar > & buffer() const
Retunrs a reference to the last received buffer.
Definition: utils.hh:832
static Queue & get()
Get a reference to the global instance of the queue.
Definition: queue.cc:15
DebugStore()
Constrctor.
Definition: utils.hh:803
virtual void config(const Config &src_cfg)
Configures the raw sink.
Definition: utils.hh:568
virtual void config(const Config &src_cfg)
Configures the cast node.
Definition: utils.cc:20
Typed sink.
Definition: node.hh:192
Extracts the real or imaginary part of a complex valued data stream.
Definition: utils.hh:17
Scale(float scale=1, Scalar shift=0)
Constructs the scaling node.
Definition: utils.hh:600
double _shift
The frequency shift in Hz ( ).
Definition: utils.hh:510
double _sample_rate
The current sample-rate.
Definition: utils.hh:790
Complex (aka I/Q) type of unsigned 16b ints.
Definition: node.hh:49
void setBalance(double balance)
Sets the I/Q balance.
Definition: utils.hh:153
Definition: autocast.hh:8
size_t numBuffers() const
Returns the max.
Definition: node.hh:89
bool isEmpty() const
Returns true if the buffer is invalid/empty.
Definition: buffer.hh:77
Real signed 8b ints.
Definition: node.hh:42
Definition: operators.hh:9
StreamSource(std::istream &stream, double sample_rate=1, size_t buffersize=1024)
Constructs a raw input source.
Definition: utils.hh:529
size_t storageSize() const
Returns the raw buffer size in bytes.
Definition: buffer.hh:75
Performs a frequency shift on a complex input signal, by multiplying it with .
Definition: utils.hh:437
ToComplex(double scale=1.0)
Constructor.
Definition: utils.hh:215
void stop()
Signals the queue to stop processing.
Definition: queue.cc:64
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
int refCount() const
Returns the reference counter.
Definition: buffer.hh:84
Explicit type cast node.
Definition: utils.hh:267
SignedToUnsigned()
Constructor with optional scaleing.
Definition: utils.cc:106
virtual void config(const Config &src_cfg)
Configures the node.
Definition: utils.hh:809
Traits< iScalar >::SScalar iSScalar
Specifies the input super scalar.
Definition: utils.hh:271
Buffer< Scalar > _buffer
The output buffer.
Definition: utils.hh:792
virtual void process(const Buffer< Scalar > &buffer, bool allow_overwrite)
Stores the given buffer.
Definition: utils.hh:824
virtual void process(const Buffer< iScalar > &buffer, bool allow_overwrite)
Performs the type-cast node.
Definition: utils.hh:318
virtual void process(const Buffer< std::complex< Scalar > > &buffer, bool allow_overwrite)
Performs the frequency shift.
Definition: utils.hh:497
size_t size() const
Returns the number of elements of type T in this buffer.
Definition: buffer.hh:166
bool hasType() const
If true, the configuration has a type.
Definition: node.hh:69
int32_t _imagFact
Scaleing factor for the imaginary part.
Definition: utils.hh:201
FreqShift(double shift, Scalar scale=1.0)
Constructs a frequency shift node with optional scaleing of the result.
Definition: utils.hh:441
std::ostream & _stream
The output stream.
Definition: utils.hh:587
void setScale(double scale)
Sets the scaling.
Definition: utils.hh:335
virtual ~DebugDump()
Destructor.
Definition: utils.hh:858
Real 64b floats aka. "double".
Definition: node.hh:46
Dumps the received uin8_t byte-stream as (ASCII) text.
Definition: utils.hh:888
char * data() const
Returns the pointer to the data of the buffer view.
Definition: buffer.hh:69
Real unsigned 16b ints.
Definition: node.hh:43
size_t _buffer_size
The size of the buffer.
Definition: utils.hh:975
AGC(double tau=0.1, double target=0)
Constructor.
Definition: utils.hh:662
virtual void setConfig(const Config &config)
Stores the configuration and propergates it if the configuration has been changed.
Definition: node.cc:98
virtual void config(const Config &src_cfg)
Configures the node.
Definition: utils.hh:222
Buffer< T > head(size_t n) const
Returns a new view on this buffer.
Definition: buffer.hh:237
double _scale
The scale.
Definition: utils.hh:257
void _process_int16(const RawBuffer &in, const RawBuffer &out)
Performs the int16 -> uint16 cast.
Definition: utils.cc:181
Buffer< Scalar > _buffer
The output buffer.
Definition: utils.hh:977
GWNSource(double sample_rate, size_t buffer_size=1024)
Constructor.
Definition: utils.hh:911
double balance() const
Retunrs the balance.
Definition: utils.hh:145
double tau() const
Returns the time-constant of the AGC.
Definition: utils.hh:713
float _sd
The averaged std.
Definition: utils.hh:784
Selects the real part of a complex signal.
Definition: utils.hh:83
std::ostream & _stream
A reference to the output stream.
Definition: utils.hh:883
virtual ~UnsignedToSigned()
Destructor.
Definition: utils.cc:15
Buffer< Scalar > _buffer
The output buffer.
Definition: utils.hh:72
virtual void process(const Buffer< std::complex< Scalar > > &buffer, bool allow_overwrite)
Processes the incomming data.
Definition: utils.hh:56
virtual void process(const Buffer< Scalar > &buffer, bool allow_overwrite)
Dumps the buffer into the stream as raw data.
Definition: utils.hh:580
virtual ~IQBalance()
Destructor.
Definition: utils.hh:140
double _sample_rate
The current sample rate.
Definition: utils.hh:516
void log(const LogMessage &message)
Logs a message.
Definition: logger.cc:100
Traits< Scalar >::SScalar SScalar
The internal used compute scalar.
Definition: utils.hh:117
RealImagPart(bool select_real, double scale=1.0)
Constructor.
Definition: utils.hh:22
double _mean
The mean value of the GWN.
Definition: utils.hh:979
Type type() const
Returns the type.
Definition: node.hh:71
void _process_int8(const RawBuffer &in, const RawBuffer &out)
Performs the cast for uint8 -> int8.
Definition: utils.cc:78
Selects the imaginary part of a complex signal.
Definition: utils.hh:98
virtual void process(const Buffer< Scalar > &buffer, bool allow_overwrite)
Performs the scaleing.
Definition: utils.hh:629
Buffer< Scalar > _view
A view to the last data received.
Definition: utils.hh:840
virtual void config(const Config &src_cfg)
Configures the type-cast node.
Definition: utils.hh:285
Buffer< std::complex< Scalar > > _buffer
The output buffer.
Definition: utils.hh:508
DebugDump(std::ostream &stream=std::cerr)
Constructor.
Definition: utils.hh:851
void(UnsignedToSigned::* _process)(const RawBuffer &in, const RawBuffer &out)
Type-cast callback.
Definition: utils.hh:393
Performs a reinterprete cast from an unsinged value to a singed one.
Definition: utils.hh:404
Simple scaling node.
Definition: utils.hh:596
iScalar _shift
Another scaling, using integer shift operation (faster).
Definition: utils.hh:363
float _scale
Holds the scaleing.
Definition: utils.hh:397
A simple node, that allows to balance an IQ signal.
Definition: utils.hh:113
Buffer< std::complex< Scalar > > _buffer
The working buffer.
Definition: utils.hh:203
static Type typeId()
Returns the type-id of the template type.
double shift() const
Returns the frequency shift.
Definition: utils.hh:454
static Logger & get()
Returns the singleton instance of the logger.
Definition: logger.cc:89
Reads raw samples from an imput stream, (ie a file).
Definition: utils.hh:525
virtual void config(const Config &src_cfg)
Configures the dump-node.
Definition: utils.hh:863
Scalar _shift
Alternative formulation for the scaling, using integer shift operators.
Definition: utils.hh:650
Dumps buffers in a human readable form.
Definition: utils.hh:847
Real 32b floats aka. "float".
Definition: node.hh:45
bool _select_real
Real/Imag selection.
Definition: utils.hh:74
The configuration error class.
Definition: exception.hh:24
TextDump(std::ostream &stream=std::cerr)
Constructor.
Definition: utils.cc:193
A log message.
Definition: logger.hh:22
Traits< oScalar >::SScalar oSScalar
Specified the output super scalar.
Definition: utils.hh:273
Keeps a copy of the last buffer received.
Definition: utils.hh:799
size_t bufferSize() const
Returns the max.
Definition: node.hh:83
void next()
Samples and emits the next chunk of data.
Definition: utils.hh:941
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
virtual void config(const Config &src_cfg)
Configures the scaleing node.
Definition: utils.hh:612
virtual void process(const Buffer< uint8_t > &buffer, bool allow_overwrite)
Processes the input stream.
Definition: utils.cc:213
virtual void handleBuffer(const RawBuffer &buffer, bool allow_overwrite)
Performs the cast.
Definition: utils.cc:64
std::istream & _stream
The input stream.
Definition: utils.hh:548
Basic interface of all Sinks.
Definition: node.hh:174
float _lambda
One over the time-constant.
Definition: utils.hh:782
char * ptr() const
Returns the pointer to the data (w/o view).
Definition: buffer.hh:67
Complex (aka I/Q) type of signed 8b ints.
Definition: node.hh:48
float _scale
The scaling.
Definition: utils.hh:648
Buffer< Scalar > _buffer
The output buffer.
Definition: utils.hh:550
void clear()
Clears the buffer.
Definition: utils.hh:834
void setTau(double tau)
Sets the time-constant of the AGC.
Definition: utils.hh:718
void _process_int8(const RawBuffer &in, const RawBuffer &out)
Performs the int8 -> uint8 cast.
Definition: utils.cc:172
bool _do_scale
If true, the output gets scaled.
Definition: utils.hh:359
int32_t _realFact
Scaleing factor for the real part.
Definition: utils.hh:199
Tiny helper node to transform a real part into a complex, including a possible type-cast.
Definition: utils.hh:211
RealPart(double scale=1.0)
Constructor.
Definition: utils.hh:87
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
std::complex< double > _factor
The current exponental factor, gets updated for every sample.
Definition: utils.hh:514
virtual void config(const Config &src_cfg)
Configures the node.
Definition: utils.hh:29
void unref()
Dereferences the buffer.
Definition: buffer.cc:63
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
UnsignedToSigned(float scale=1.0)
Constructor with optional scaleing.
Definition: utils.cc:9
Buffer< oScalar > _buffer
The output buffer, unused if the type-cast is performed in-place .
Definition: utils.hh:365
StreamSink(std::ostream &stream)
Constructor.
Definition: utils.hh:561
bool enabled() const
Returns true, if the AGC is enabled.
Definition: utils.hh:693
std::complex< double > _delta
.
Definition: utils.hh:518
virtual void config(const Config &src_cfg)
Configures the sink.
Definition: utils.cc:200
float _target
The target level of the output signal.
Definition: utils.hh:786
Forward declaration of type tratis template.
Definition: traits.hh:20
virtual ~GWNSource()
Destructor.
Definition: utils.hh:934
Buffer< Scalar > _buffer
The output buffer, unused if the scaling is performed in-place.
Definition: utils.hh:646
float _gain
The current gain factor.
Definition: utils.hh:788
RawBuffer _buffer
The output buffer, unused if the cast is performed in-place.
Definition: utils.hh:427
bool _can_overwrite
If true, the type-cast (an scaleing) can be performed in-place.
Definition: utils.hh:357
void _process(const Buffer< std::complex< Scalar > > &in, const Buffer< std::complex< Scalar > > &out)
The actual implementation.
Definition: utils.hh:190
An automatic gain control node.
Definition: utils.hh:658
void next()
Reads the next chunk.
Definition: utils.hh:538
virtual void config(const Config &src_cfg)
Configures the frequency shift node.
Definition: utils.hh:464
virtual void config(const Config &src_cfg)
Configures the AGC node.
Definition: utils.hh:725
Serializes the incomming buffers as raw data.
Definition: utils.hh:557
virtual void process(const Buffer< std::complex< Scalar > > &buffer, bool allow_overwrite)
Processes a buffer.
Definition: utils.hh:178
ImagPart(double scale=1.0)
Constructor.
Definition: utils.hh:102
bool hasBufferSize() const
If true, the configuration has a buffer size.
Definition: node.hh:81
virtual ~FreqShift()
Destructor.
Definition: utils.hh:449
void _getNormal(double &a, double &b)
Sample two std.
Definition: utils.hh:957
Complex (aka I/Q) type of 64bit floats aka. std::complex.
Definition: node.hh:52
virtual void config(const Config &src_cfg)
Configures the node.
Definition: utils.hh:167
double sampleRate() const
Returns the sample rate.
Definition: node.hh:77
bool _enabled
If true, the automatic gain adjustment is enabled.
Definition: utils.hh:778
IQBalance(double balance=0.0)
Constructor.
Definition: utils.hh:124