OBECA Receive Process
Public Member Functions | List of all members
LimeSdrReader Class Reference

Interface to LimeSDR via LimeSuite. More...

#include <LimeSdrReader.h>

Public Member Functions

 LimeSdrReader (const libconfig::Config &cfg)
 Default constructor. More...
 
virtual ~LimeSdrReader ()
 Default destructor.
 
bool init (uint8_t device_index, const char *sample_file, const char *write_sample_file)
 Initializes the SDR interface and creates a ring buffer according to the params from Cfg.
 
bool setSampleRate (unsigned sample_rate)
 Adjust the sample rate.
 
bool tune (uint32_t frequency, uint32_t sample_rate, uint32_t bandwidth, double gain, const std::string &antenna)
 Tune the SDR to the desired frequency, and set gain, filter and antenna parameters.
 
void start ()
 Start reading samples from the SDR.
 
void stop ()
 Stop reading samples from the SDR.
 
void clear_buffer ()
 Clear all samples from the rx buffers.
 
int getSamples (cf_t *data, uint32_t nsamples, srslte_timestamp_t *rx_time)
 Store nsamples count samples into the buffer at data. More...
 
double get_sample_rate ()
 Get current sample rate.
 
double get_frequency ()
 Get current center frequency.
 
unsigned get_filter_bw ()
 Get current filter bandwidth.
 
double get_gain ()
 Get current gain.
 
double get_buffer_level ()
 Get current ringbuffer level (0 = empty . More...
 
std::string get_antenna ()
 Get current antenna port.
 
uint32_t rssi ()
 Get RSSI estimate (disabled at the moment)
 

Detailed Description

Interface to LimeSDR via LimeSuite.

Sets up the SDR, reads samples from it, and handles a ringbuffer for the received samples.

Definition at line 36 of file LimeSdrReader.h.

Constructor & Destructor Documentation

◆ LimeSdrReader()

LimeSdrReader::LimeSdrReader ( const libconfig::Config &  cfg)
inlineexplicit

Default constructor.

Parameters
cfgConfig singleton reference

Definition at line 43 of file LimeSdrReader.h.

44  : _buffer(bev::linear_ringbuffer::delayed_init {})
45  , _overflows(0)
46  , _underflows(0)
47  , _cfg(cfg)
48  , _readerThread{} {}

Member Function Documentation

◆ get_buffer_level()

double LimeSdrReader::get_buffer_level ( )
inline

Get current ringbuffer level (0 = empty .

. 1 = full)

Definition at line 117 of file LimeSdrReader.h.

117 { if (!_buffer_ready) { return 0; } return static_cast<double>(_buffer.size()) / static_cast<double>(_buffer.capacity()); }

◆ getSamples()

auto LimeSdrReader::getSamples ( cf_t *  data,
uint32_t  nsamples,
srslte_timestamp_t *  rx_time 
)

Store nsamples count samples into the buffer at data.

Parameters
dataBuffer pointer
nsamplessample count
rx_timeunused

Definition at line 306 of file LimeSdrReader.cpp.

308  {
309  std::chrono::steady_clock::time_point entered = {};
310  entered = std::chrono::steady_clock::now();
311 
312  int64_t required_time_us = (1000000.0/_sampleRate) * nsamples;
313  size_t cnt = nsamples * sizeof(cf_t);
314 
315  if (_high_watermark_reached && _buffer.size() < (_sampleRate / 1000.0) * 10 * sizeof(cf_t)) {
316  _high_watermark_reached = false;
317  }
318 
319  if (!_high_watermark_reached) {
320  while (_buffer.size() < (_sampleRate / 1000.0) * (_buffer_ms / 2.0) * sizeof(cf_t)) {
321  std::this_thread::sleep_for(std::chrono::microseconds(500));
322  }
323  spdlog::debug("Filled ringbuffer to half capacity");
324  _high_watermark_reached = true;
325  }
326 
327  memcpy(data, _buffer.read_head(), cnt);
328  _buffer.consume(cnt);
329 
330  if (_buffer.size() < (_sampleRate / 1000.0) * (_buffer_ms / 2.0) * sizeof(cf_t)) {
331  required_time_us += 500;
332  } else {
333  required_time_us -= 500;
334  }
335 
336  spdlog::debug("read {} samples, adjusted required {} us, delta {} us, sleep adj {}, sleeping for {} us",
337  nsamples,
338  std::chrono::microseconds(required_time_us).count(),
339  std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - _last_read).count(),
340  _sleep_adjustment,
341  (std::chrono::microseconds(_sleep_adjustment + required_time_us) - std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - _last_read)).count());
342 
343  std::chrono::microseconds sleep = (std::chrono::microseconds(_sleep_adjustment + required_time_us) - std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - _last_read));
344 
345  if (sleep.count() > 0) {
346  std::this_thread::sleep_for(sleep);
347  _sleep_adjustment = 0;
348  } else if (sleep.count() > -100000) {
349  _sleep_adjustment = sleep.count();
350  }
351 
352  _last_read = std::chrono::steady_clock::now();
353  return 0;
354 }

The documentation for this class was generated from the following files: