You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libsdr/src/siggen.hh

163 lines
4.4 KiB
C++

#ifndef __SDR_SIGGEN_HH__
#define __SDR_SIGGEN_HH__
#include "node.hh"
namespace sdr {
/** Arbitrary function generator.
* @ingroup sources */
template <class Scalar>
class SigGen: public Source
{
public:
/** Constructs the function generator. */
SigGen(double samplerate, size_t buffersize, double tmax=-1)
: Source(), _sampleRate(samplerate), _dt(1./_sampleRate), _t(0), _tMax(tmax), _scale(1),
_bufferSize(buffersize), _buffer(buffersize)
{
switch (Config::typeId<Scalar>()) {
case Config::Type_u8:
case Config::Type_s8:
case Config::Type_cu8:
case Config::Type_cs8:
_scale = 1<<6; break;
case Config::Type_u16:
case Config::Type_s16:
case Config::Type_cu16:
case Config::Type_cs16:
_scale = 1<<14; break;
default:
_scale = 1; break;
}
this->setConfig(Config(Config::typeId<Scalar>(), samplerate, buffersize, 1));
}
/** Destructor. */
virtual ~SigGen() {}
/** Computes the next buffer. This function can be connected to the idle signal of the @c Queue. */
void next() {
// Stop processing once the max time elapsed
if ((_tMax>0) && (_t >= _tMax)) { Queue::get().stop(); return; }
// Assemble signal
for (size_t i=0; i<_bufferSize; i++) {
_buffer[i] = 0;
if (_signals.size() > 0) {
std::list< std::vector<double> >::iterator item = _signals.begin();
for (; item != _signals.end(); item++) {
_buffer[i] += (_scale*((*item)[1] * sin(2*M_PI*(*item)[0]*_t + (*item)[2]))/_signals.size());
}
}
_t += _dt;
}
// Send buffer
this->send(_buffer);
}
/** Add a sine function to the function generator. */
void addSine(double freq, double ampl=1, double phase=0) {
std::vector<double> tmp(3); tmp[0] = freq; tmp[1] = ampl; tmp[2] = phase;
_signals.push_back(tmp);
}
protected:
/** The sample rate of the function generator. */
double _sampleRate;
/** The sample period. */
double _dt;
/** The current time. */
double _t;
/** The maximum time. */
double _tMax;
/** The scaling of the signal. */
double _scale;
/** A list of functions. */
std::list< std::vector<double> > _signals;
/** The size of the output buffer. */
size_t _bufferSize;
/** The output buffer. */
Buffer<Scalar> _buffer;
};
/** Arbitrary function generator.
* @ingroup sources */
template <class Scalar>
class IQSigGen: public Source
{
public:
/** Constructs the function generator. */
IQSigGen(double samplerate, size_t buffersize, double tmax=-1)
: Source(), _sampleRate(samplerate), _dt(1./_sampleRate), _t(0), _tMax(tmax), _scale(1),
_bufferSize(buffersize), _buffer(buffersize)
{
switch (Config::typeId<Scalar>()) {
case Config::Type_cu8:
case Config::Type_cs8:
_scale = 1<<6; break;
case Config::Type_cu16:
case Config::Type_cs16:
_scale = 1<<14; break;
default:
_scale = 1; break;
}
this->setConfig(Config(Config::typeId< std::complex<Scalar> >(), samplerate, buffersize, 1));
}
/** Destructor. */
virtual ~IQSigGen() {}
/** Computes the next buffer. This function can be connected to the idle signal of the @c Queue. */
void next() {
// Stop processing once the max time elapsed
if ((_tMax>0) && (_t >= _tMax)) { Queue::get().stop(); return; }
// Assemble signal
for (size_t i=0; i<_bufferSize; i++) {
_buffer[i] = 0;
if (_signals.size() > 0) {
std::list< std::vector<double> >::iterator item = _signals.begin();
for (; item != _signals.end(); item++) {
_buffer[i] += (_scale*((*item)[1] * std::exp(std::complex<double>(0, 2*M_PI*(*item)[0]*_t + (*item)[2])))/double(_signals.size()));
}
}
_t += _dt;
}
// Send buffer
this->send(_buffer);
}
/** Add a sine function to the function generator. */
void addSine(double freq, double ampl=1, double phase=0) {
std::vector<double> tmp(3); tmp[0] = freq; tmp[1] = ampl; tmp[2] = phase;
_signals.push_back(tmp);
}
protected:
/** The sample rate of the function generator. */
double _sampleRate;
/** The sample period. */
double _dt;
/** The current time. */
double _t;
/** The maximum time. */
double _tMax;
/** The scaling of the signal. */
double _scale;
/** A list of functions. */
std::list< std::vector<double> > _signals;
/** The size of the output buffer. */
size_t _bufferSize;
/** The output buffer. */
Buffer< std::complex<Scalar> > _buffer;
};
}
#endif // __SDR_SIGGEN_HH__