autocast.hh
#ifndef __SDR_AUTOCAST_HH__
#define __SDR_AUTOCAST_HH__
#include "node.hh"
#include "traits.hh"
#include "logger.hh"
namespace sdr {
template <class Scalar>
class AutoCast: public SinkBase, public Source
{
public:
AutoCast()
: SinkBase(), Source(), _buffer(), _cast(0)
{
// pass...
}
virtual void config(const Config &src_cfg) {
// Requires buffer size, sample rate and type:
if ((Config::Type_UNDEFINED==src_cfg.type()) || (0==src_cfg.sampleRate()) || (0==src_cfg.bufferSize())) { return; }
// Check type cast combination
if (Config::Type_s8 == Traits<Scalar>::scalarId) {
switch (src_cfg.type()) {
case Config::Type_u8: _cast = _uint8_int8; break;
case Config::Type_s8: _cast = _identity; break;
case Config::Type_u16: _cast = _uint16_int8; break;
case Config::Type_s16: _cast = _int16_int8; break;
default: break;
}
} else if (Config::Type_cs8 == Traits<Scalar>::scalarId) {
switch (src_cfg.type()) {
case Config::Type_u8: _cast = _uint8_cint8; break;
case Config::Type_s8: _cast = _int8_cint8; break;
case Config::Type_cu8: _cast = _uint8_int8; break;
case Config::Type_cs8: _cast = _identity; break;
case Config::Type_u16: _cast = _uint16_cint8; break;
case Config::Type_s16: _cast = _int16_cint8; break;
case Config::Type_cu16: _cast = _uint16_int8; break;
case Config::Type_cs16: _cast = _int16_int8; break;
default: break;
}
} else if (Config::Type_s16 == Traits<Scalar>::scalarId) {
switch (src_cfg.type()) {
case Config::Type_u8: _cast = _uint8_int16; break;
case Config::Type_s8: _cast = _int8_int16; break;
case Config::Type_u16: _cast = _uint16_int16; break;
case Config::Type_s16: _cast = _identity; break;
default: break;
}
} else if (Config::Type_cs16 == Traits<Scalar>::scalarId) {
switch (src_cfg.type()) {
case Config::Type_u8: _cast = _uint8_cint16; break;
case Config::Type_s8: _cast = _int8_cint16; break;
case Config::Type_cu8: _cast = _uint8_int16; break;
case Config::Type_cs8: _cast = _int8_int16; break;
case Config::Type_u16: _cast = _uint16_cint16; break;
case Config::Type_s16: _cast = _int16_cint16; break;
case Config::Type_cu16: _cast = _uint16_int16; break;
case Config::Type_cs16: _cast = _identity; break;
default: break;
}
}
// Check if there exists a cast to the required type
if (0 == _cast) {
ConfigError err;
err << "AutoCast: Can not cast from type " << src_cfg.type() << " to " << Traits<Scalar>::scalarId;
throw err;
}
// Allocate buffer
_buffer = Buffer<Scalar>(src_cfg.bufferSize());
LogMessage msg(LOG_DEBUG);
msg << "Configure AutoCast node:" << std::endl
<< " input type: " << src_cfg.type() << std::endl
<< " output type: " << Traits<Scalar>::scalarId;
Logger::get().log(msg);
// Propergate config
this->setConfig(Config(Config::typeId<Scalar>(), src_cfg.sampleRate(), src_cfg.bufferSize(), 1));
}
virtual void handleBuffer(const RawBuffer &buffer, bool allow_overwrite) {
// If no conversion is selected
if (0 == _cast) { return; }
// If the identity conversion is selected -> forward buffer
if (_identity == _cast) { this->send(buffer, allow_overwrite); return; }
// Otherwise cast
size_t bytes = _cast(buffer, _buffer);
this->send(RawBuffer(_buffer, 0, bytes), false);
}
protected:
Buffer<Scalar> _buffer;
size_t (*_cast)(const RawBuffer &in, const RawBuffer &out);
protected:
static size_t _identity(const RawBuffer &in, const RawBuffer &out) {
memcpy(out.ptr(), in.data(), in.bytesLen());
return in.bytesLen();
}
static size_t _uint8_int8(const RawBuffer &in, const RawBuffer &out) {
size_t N = in.bytesLen();
for (size_t i=0; i<N; i++) {
reinterpret_cast<int8_t *>(out.data())[i] =
int16_t(reinterpret_cast<uint8_t *>(in.data())[i]) - 127;
}
return N;
}
static size_t _uint16_int8(const RawBuffer &in, const RawBuffer &out) {
size_t N = in.bytesLen()/2;
for (size_t i=0; i<N; i++) {
reinterpret_cast<int8_t *>(out.data())[i] =
int16_t(reinterpret_cast<uint16_t *>(in.data())[i]>>8) - 127;
}
return N;
}
static size_t _int16_int8(const RawBuffer &in, const RawBuffer &out) {
size_t N = in.bytesLen()/2;
for (size_t i=0; i<N; i++) {
reinterpret_cast<int8_t *>(out.data())[i] =
reinterpret_cast<int16_t *>(in.data())[i]>>8;
}
return N;
}
static size_t _uint8_cint8(const RawBuffer &in, const RawBuffer &out) {
size_t N = in.bytesLen();
uint8_t *values = reinterpret_cast<uint8_t *>(in.data());
for (size_t i=0; i<N; i++) {
reinterpret_cast<std::complex<int8_t> *>(out.data())[i] =
(int16_t(values[i])-127);
}
return 2*N;
}
static size_t _int8_cint8(const RawBuffer &in, const RawBuffer &out) {
size_t N = in.bytesLen();
for (size_t i=0; i<N; i++) {
reinterpret_cast<std::complex<int8_t> *>(out.data())[i] =
reinterpret_cast<int8_t *>(in.data())[i];
}
return 2*N;
}
static size_t _uint16_cint8(const RawBuffer &in, const RawBuffer &out) {
size_t N = in.bytesLen()/2;
for (size_t i=0; i<N; i++) {
reinterpret_cast<std::complex<int8_t> *>(out.data())[i]
= int32_t(reinterpret_cast<int16_t *>(in.data())[i]>>8)-((2<<15)-1);
}
return 2*N;
}
static size_t _int16_cint8(const RawBuffer &in, const RawBuffer &out) {
size_t N = in.bytesLen()/2;
for (size_t i=0; i<N; i++) {
reinterpret_cast<std::complex<int8_t> *>(out.data())[i] = reinterpret_cast<int16_t *>(in.data())[i]>>8;
}
return 2*N;
}
static size_t _uint8_int16(const RawBuffer &in, const RawBuffer &out) {
size_t N = in.bytesLen();
int8_t *values = reinterpret_cast<int8_t *>(in.data());
for (size_t i=0; i<N; i++) {
reinterpret_cast<int16_t *>(out.data())[i] = (int16_t(values[i])-127)<<8;
}
return 2*N;
}
static size_t _int8_int16(const RawBuffer &in, const RawBuffer &out) {
size_t N = in.bytesLen();
int8_t *values = reinterpret_cast<int8_t *>(in.data());
for (size_t i=0; i<N; i++) {
reinterpret_cast<int16_t *>(out.data())[i] = int16_t(values[i])<<8;
}
return 2*N;
}
static size_t _uint16_int16(const RawBuffer &in, const RawBuffer &out) {
size_t N = in.bytesLen()/2;
uint16_t *values = reinterpret_cast<uint16_t *>(in.data());
for (size_t i=0; i<N; i++) {
reinterpret_cast<int16_t *>(out.data())[i] = int32_t(values[i])-((2<<15)-1);
}
return 2*N;
}
static size_t _uint8_cint16(const RawBuffer &in, const RawBuffer &out) {
size_t N = in.bytesLen();
uint8_t *values = reinterpret_cast<uint8_t *>(in.data());
for (size_t i=0; i<N; i++) {
reinterpret_cast<std::complex<int16_t> *>(out.data())[i]
= std::complex<int16_t>((int16_t(values[i])-127)<<8);
}
return 4*N;
}
static size_t _int8_cint16(const RawBuffer &in, const RawBuffer &out) {
size_t N = in.bytesLen();
int8_t *values = reinterpret_cast<int8_t *>(in.data());
for (size_t i=0; i<N; i++) {
reinterpret_cast<std::complex<int16_t> *>(out.data())[i]
= std::complex<int16_t>(int16_t(values[i])*(1<<8));
}
return 4*N;
}
static size_t _uint16_cint16(const RawBuffer &in, const RawBuffer &out) {
size_t N = in.bytesLen()/2;
uint16_t *values = reinterpret_cast<uint16_t *>(in.data());
for (size_t i=0; i<N; i++) {
reinterpret_cast<std::complex<int16_t> *>(out.data())[i]
= std::complex<int16_t>(int32_t(values[i])-(1<<15));
}
return 4*N;
}
static size_t _int16_cint16(const RawBuffer &in, const RawBuffer &out) {
size_t N = in.bytesLen()/2;
int16_t *values = reinterpret_cast<int16_t *>(in.data());
for (size_t i=0; i<N; i++) {
reinterpret_cast<std::complex<int16_t> *>(out.data())[i] = std::complex<int16_t>(values[i]);
}
return 4*N;
}
};
}
#endif // __SDR_AUTOCAST_HH__
sdr::AutoCast::_int16_int8
static size_t _int16_int8(const RawBuffer &in, const RawBuffer &out)
int16 -> int8
Definition: autocast.hh:137
sdr::Config
A collection of configuration information that is send by a source to all connected sinks to properga...
Definition: node.hh:35
sdr::RawBuffer
Base class of all buffers, represents an untyped array of bytes.
Definition: buffer.hh:32
sdr::AutoCast::_buffer
Buffer< Scalar > _buffer
Output buffer.
Definition: autocast.hh:105
sdr::AutoCast::_uint16_cint8
static size_t _uint16_cint8(const RawBuffer &in, const RawBuffer &out)
uint16 -> complex int 8.
Definition: autocast.hh:168
sdr::Config::Type_s16
Real signed 16b ints.
Definition: node.hh:44
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::Config::Type_cu16
Complex (aka I/Q) type of unsigned 16b ints.
Definition: node.hh:49
sdr
Definition: autocast.hh:8
sdr::Config::Type_s8
Real signed 8b ints.
Definition: node.hh:42
sdr::Source
Generic source class.
Definition: node.hh:213
sdr::Config::Type_u8
Real unsigned 8b ints.
Definition: node.hh:41
sdr::RawBuffer::bytesLen
size_t bytesLen() const
Returns the size of the buffer by the view.
Definition: buffer.hh:73
sdr::AutoCast::_uint8_int16
static size_t _uint8_int16(const RawBuffer &in, const RawBuffer &out)
uint8 -> int16.
Definition: autocast.hh:187
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::AutoCast::_int8_cint8
static size_t _int8_cint8(const RawBuffer &in, const RawBuffer &out)
int8 -> complex int8.
Definition: autocast.hh:158
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::AutoCast::handleBuffer
virtual void handleBuffer(const RawBuffer &buffer, bool allow_overwrite)
Needs to be implemented by any sub-type to process the received data.
Definition: autocast.hh:92
sdr::Logger::log
void log(const LogMessage &message)
Logs a message.
Definition: logger.cc:100
sdr::Config::type
Type type() const
Returns the type.
Definition: node.hh:71
sdr::AutoCast::_cast
size_t(* _cast)(const RawBuffer &in, const RawBuffer &out)
Cast function.
Definition: autocast.hh:107
sdr::AutoCast::_uint8_int8
static size_t _uint8_int8(const RawBuffer &in, const RawBuffer &out)
uint8_t -> int8_t
Definition: autocast.hh:117
sdr::Logger::get
static Logger & get()
Returns the singleton instance of the logger.
Definition: logger.cc:89
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::AutoCast::_int8_int16
static size_t _int8_int16(const RawBuffer &in, const RawBuffer &out)
int8 -> int16.
Definition: autocast.hh:197
sdr::AutoCast::_int16_cint8
static size_t _int16_cint8(const RawBuffer &in, const RawBuffer &out)
int16 -> complex int 8.
Definition: autocast.hh:178
sdr::AutoCast::AutoCast
AutoCast()
Constructor.
Definition: autocast.hh:18
sdr::AutoCast::_int16_cint16
static size_t _int16_cint16(const RawBuffer &in, const RawBuffer &out)
int16 -> complex int16.
Definition: autocast.hh:250
sdr::AutoCast
This class performs some automatic casts to a certain buffer type (if possible) specified by the temp...
Definition: autocast.hh:14
sdr::SinkBase
Basic interface of all Sinks.
Definition: node.hh:174
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::AutoCast::config
virtual void config(const Config &src_cfg)
Configures the auto cast node.
Definition: autocast.hh:25
sdr::AutoCast::_uint8_cint16
static size_t _uint8_cint16(const RawBuffer &in, const RawBuffer &out)
unsinged int8 -> complex int16.
Definition: autocast.hh:217
sdr::AutoCast::_int8_cint16
static size_t _int8_cint16(const RawBuffer &in, const RawBuffer &out)
int8 -> complex int16.
Definition: autocast.hh:228
sdr::Config::Type_cs16
Complex (aka I/Q) type of signed 16b ints.
Definition: node.hh:50
sdr::AutoCast::_uint16_int16
static size_t _uint16_int16(const RawBuffer &in, const RawBuffer &out)
uint16 -> int16.
Definition: autocast.hh:207
sdr::Config::Type_cu8
Complex (aka I/Q) type of unsigned 8b ints.
Definition: node.hh:47
sdr::AutoCast::_uint16_int8
static size_t _uint16_int8(const RawBuffer &in, const RawBuffer &out)
uint16 -> int8
Definition: autocast.hh:127
sdr::Traits
Forward declaration of type tratis template.
Definition: traits.hh:20
sdr::AutoCast::_uint16_cint16
static size_t _uint16_cint16(const RawBuffer &in, const RawBuffer &out)
uint16 -> complex int16.
Definition: autocast.hh:239
sdr::AutoCast::_uint8_cint8
static size_t _uint8_cint8(const RawBuffer &in, const RawBuffer &out)
uint8 -> complex int8.
Definition: autocast.hh:147
sdr::AutoCast::_identity
static size_t _identity(const RawBuffer &in, const RawBuffer &out)
Performs no cast at all.
Definition: autocast.hh:111
sdr::Buffer< Scalar >
sdr::Config::sampleRate
double sampleRate() const
Returns the sample rate.
Definition: node.hh:77