freqshift.hh
#ifndef __SDR_FREQSHIFT_HH__
#define __SDR_FREQSHIFT_HH__
#include "config.hh"
#include "traits.hh"
#include "node.hh"
#include "operators.hh"
namespace sdr {
template <class Scalar>
class FreqShiftBase
{
public:
typedef std::complex<Scalar> CScalar;
typedef typename Traits<Scalar>::SScalar SScalar;
typedef std::complex<SScalar> CSScalar;
public:
FreqShiftBase(double F, double Fs)
: _freq_shift(F), _Fs(Fs), _lut_inc(0), _lut_count(0), _lut(_lut_size)
{
// Allocate and assemble LUT
// Allocate LUT for (neg) frequency shift
_lut = Buffer<CSScalar>(_lut_size);
for (size_t i=0; i<_lut_size; i++) {
_lut[i] = double(1 << Traits<Scalar>::shift) *
std::exp(std::complex<double>(0,-(2*M_PI*i)/_lut_size));
}
}
virtual ~FreqShiftBase() {
_lut.unref();
}
inline double sampleRate() const { return _Fs; }
virtual void setSampleRate(double Fs) {
_Fs = Fs; _update_lut_incr();
}
inline double frequencyShift() const { return _freq_shift; }
virtual void setFrequencyShift(double F) {
_freq_shift = F; _update_lut_incr();
}
inline CSScalar applyFrequencyShift(CSScalar value)
{
// If frequency shift is actually 0 -> return
if (0 == _lut_inc) { return value; }
// Get index, idx = (_lut_count/256)
size_t idx = (_lut_count>>8);
// Handle negative frequency shifts
if (0 > _freq_shift) { idx = _lut_size - idx - 1; }
// Apply
value = ((_lut[idx] * value) >> Traits<Scalar>::shift);
// Incement _lut_count
_lut_count += _lut_inc;
// _lut_count modulo (_lut_size*256)
while (_lut_count >= (_lut_size<<8)) { _lut_count -= (_lut_size<<8); }
// Done.
return value;
}
protected:
void _update_lut_incr() {
// Every sample increments the LUT index by lut_inc/256.
// The multiple is needed as ratio between the frequency shift _Fc and the sample rate _Fs
// may not result in an integer increment. By simply flooring _lut_size*_Fc/_Fs, the actual
// down conversion may be much smaller than actual reuqired. Hence, the counter is therefore
// incremented by the integer (256*_lut_size*_Fc/_Fs) and the index is then obtained by
// dividing _lut_count by 256 (right shift 8 bits).
_lut_inc = (_lut_size*(1<<8)*std::abs(_freq_shift))/_Fs;
_lut_count = 0;
}
protected:
double _freq_shift;
double _Fs;
size_t _lut_inc;
size_t _lut_count;
Buffer<CSScalar> _lut;
protected:
static const size_t _lut_size = 128;
};
}
#endif // FREQSHIFT_HH
sdr::FreqShiftBase::frequencyShift
double frequencyShift() const
Returns the frequency shift.
Definition: freqshift.hh:51
sdr::FreqShiftBase::_lut
Buffer< CSScalar > _lut
The LUT.
Definition: freqshift.hh:99
sdr::FreqShiftBase::setSampleRate
virtual void setSampleRate(double Fs)
Sets the sample rate and updates the LUT.
Definition: freqshift.hh:46
sdr
Definition: autocast.hh:8
sdr::FreqShiftBase::setFrequencyShift
virtual void setFrequencyShift(double F)
Sets the frequency shift and updates the LUT.
Definition: freqshift.hh:53
sdr::FreqShiftBase::_lut_inc
size_t _lut_inc
The LUT increment.
Definition: freqshift.hh:95
sdr::FreqShiftBase::~FreqShiftBase
virtual ~FreqShiftBase()
Destructor.
Definition: freqshift.hh:39
sdr::FreqShiftBase::sampleRate
double sampleRate() const
Returns the sample rate.
Definition: freqshift.hh:44
sdr::FreqShiftBase::CSScalar
std::complex< SScalar > CSScalar
The complex compute (super) scalar of the input type.
Definition: freqshift.hh:22
sdr::FreqShiftBase::FreqShiftBase
FreqShiftBase(double F, double Fs)
Constructor.
Definition: freqshift.hh:26
sdr::FreqShiftBase::CScalar
std::complex< Scalar > CScalar
The complex input signal.
Definition: freqshift.hh:18
sdr::FreqShiftBase::SScalar
Traits< Scalar >::SScalar SScalar
The compute (super) scalar of the input type.
Definition: freqshift.hh:20
sdr::FreqShiftBase
A performant implementation of a frequency-shift operation on integer signals.
Definition: freqshift.hh:14
sdr::FreqShiftBase::_update_lut_incr
void _update_lut_incr()
Updates the multiplier LUT.
Definition: freqshift.hh:78
sdr::FreqShiftBase::applyFrequencyShift
CSScalar applyFrequencyShift(CSScalar value)
Performs the frequency shift on a single sample.
Definition: freqshift.hh:58
sdr::RawBuffer::unref
void unref()
Dereferences the buffer.
Definition: buffer.cc:63
sdr::Traits
Forward declaration of type tratis template.
Definition: traits.hh:20
sdr::FreqShiftBase::_lut_count
size_t _lut_count
The LUT index counter.
Definition: freqshift.hh:97
sdr::FreqShiftBase::_freq_shift
double _freq_shift
The current frequency shift.
Definition: freqshift.hh:91
sdr::FreqShiftBase::_lut_size
static const size_t _lut_size
The size of the LUT.
Definition: freqshift.hh:103
sdr::Buffer< CSScalar >
sdr::FreqShiftBase::_Fs
double _Fs
The current sample rate.
Definition: freqshift.hh:93