libsdr  0.1.0
A simple SDR library
freqshift.hh
1 #ifndef __SDR_FREQSHIFT_HH__
2 #define __SDR_FREQSHIFT_HH__
3 
4 #include "config.hh"
5 #include "traits.hh"
6 #include "node.hh"
7 #include "operators.hh"
8 
9 namespace sdr {
10 
13 template <class Scalar>
15 {
16 public:
18  typedef std::complex<Scalar> CScalar;
20  typedef typename Traits<Scalar>::SScalar SScalar;
22  typedef std::complex<SScalar> CSScalar;
23 
24 public:
26  FreqShiftBase(double F, double Fs)
27  : _freq_shift(F), _Fs(Fs), _lut_inc(0), _lut_count(0), _lut(_lut_size)
28  {
29  // Allocate and assemble LUT
30  // Allocate LUT for (neg) frequency shift
32  for (size_t i=0; i<_lut_size; i++) {
33  _lut[i] = double(1 << Traits<Scalar>::shift) *
34  std::exp(std::complex<double>(0,-(2*M_PI*i)/_lut_size));
35  }
36  }
37 
39  virtual ~FreqShiftBase() {
40  _lut.unref();
41  }
42 
44  inline double sampleRate() const { return _Fs; }
46  virtual void setSampleRate(double Fs) {
47  _Fs = Fs; _update_lut_incr();
48  }
49 
51  inline double frequencyShift() const { return _freq_shift; }
53  virtual void setFrequencyShift(double F) {
55  }
56 
58  inline CSScalar applyFrequencyShift(CSScalar value)
59  {
60  // If frequency shift is actually 0 -> return
61  if (0 == _lut_inc) { return value; }
62  // Get index, idx = (_lut_count/256)
63  size_t idx = (_lut_count>>8);
64  // Handle negative frequency shifts
65  if (0 > _freq_shift) { idx = _lut_size - idx - 1; }
66  // Apply
67  value = ((_lut[idx] * value) >> Traits<Scalar>::shift);
68  // Incement _lut_count
70  // _lut_count modulo (_lut_size*256)
71  while (_lut_count >= (_lut_size<<8)) { _lut_count -= (_lut_size<<8); }
72  // Done.
73  return value;
74  }
75 
76 protected:
79  // Every sample increments the LUT index by lut_inc/256.
80  // The multiple is needed as ratio between the frequency shift _Fc and the sample rate _Fs
81  // may not result in an integer increment. By simply flooring _lut_size*_Fc/_Fs, the actual
82  // down conversion may be much smaller than actual reuqired. Hence, the counter is therefore
83  // incremented by the integer (256*_lut_size*_Fc/_Fs) and the index is then obtained by
84  // dividing _lut_count by 256 (right shift 8 bits).
85  _lut_inc = (_lut_size*(1<<8)*std::abs(_freq_shift))/_Fs;
86  _lut_count = 0;
87  }
88 
89 protected:
91  double _freq_shift;
93  double _Fs;
95  size_t _lut_inc;
97  size_t _lut_count;
100 
101 protected:
103  static const size_t _lut_size = 128;
104 };
105 
106 
107 }
108 
109 #endif // FREQSHIFT_HH
double frequencyShift() const
Returns the frequency shift.
Definition: freqshift.hh:51
Buffer< CSScalar > _lut
The LUT.
Definition: freqshift.hh:99
virtual void setSampleRate(double Fs)
Sets the sample rate and updates the LUT.
Definition: freqshift.hh:46
Definition: autocast.hh:8
virtual void setFrequencyShift(double F)
Sets the frequency shift and updates the LUT.
Definition: freqshift.hh:53
size_t _lut_inc
The LUT increment.
Definition: freqshift.hh:95
virtual ~FreqShiftBase()
Destructor.
Definition: freqshift.hh:39
double sampleRate() const
Returns the sample rate.
Definition: freqshift.hh:44
std::complex< SScalar > CSScalar
The complex compute (super) scalar of the input type.
Definition: freqshift.hh:22
FreqShiftBase(double F, double Fs)
Constructor.
Definition: freqshift.hh:26
std::complex< Scalar > CScalar
The complex input signal.
Definition: freqshift.hh:18
Traits< Scalar >::SScalar SScalar
The compute (super) scalar of the input type.
Definition: freqshift.hh:20
A performant implementation of a frequency-shift operation on integer signals.
Definition: freqshift.hh:14
void _update_lut_incr()
Updates the multiplier LUT.
Definition: freqshift.hh:78
CSScalar applyFrequencyShift(CSScalar value)
Performs the frequency shift on a single sample.
Definition: freqshift.hh:58
void unref()
Dereferences the buffer.
Definition: buffer.cc:63
Forward declaration of type tratis template.
Definition: traits.hh:20
size_t _lut_count
The LUT index counter.
Definition: freqshift.hh:97
double _freq_shift
The current frequency shift.
Definition: freqshift.hh:91
static const size_t _lut_size
The size of the LUT.
Definition: freqshift.hh:103
double _Fs
The current sample rate.
Definition: freqshift.hh:93