5G-MAG Reference Tools - MBMS Modem
Public Member Functions | Private Member Functions | Private Attributes | List of all members
SdrReader Class Reference

Interface to the SDR stick. More...

#include <SdrReader.h>

Collaboration diagram for SdrReader:
Collaboration graph

Public Member Functions

 SdrReader (const libconfig::Config &cfg, size_t rx_channels)
 Default constructor. More...
 
virtual ~SdrReader ()
 Default destructor. More...
 
void enumerateDevices ()
 Prints a list of all available SDR devices. More...
 
bool init (const std::string &device_args, const char *sample_file, const char *write_sample_file, bool repeat_sample_file)
 Initializes the SDR interface and creates a ring buffer according to the params from Cfg. More...
 
bool tune (uint32_t frequency, uint32_t sample_rate, uint32_t bandwidth, double gain, const std::string &antenna, bool use_agc)
 Tune the SDR to the desired frequency, and set gain, filter and antenna parameters. More...
 
void start ()
 Start reading samples from the SDR. More...
 
void stop ()
 Stop reading samples from the SDR. More...
 
void clear_buffer ()
 Clear all samples from the rx buffers. More...
 
int get_samples (cf_t *data[SRSRAN_MAX_CHANNELS], uint32_t nsamples, srsran_timestamp_t *rx_time)
 Store nsamples count samples into the buffer at data. More...
 
double get_sample_rate ()
 Get current sample rate. More...
 
double get_frequency ()
 Get current center frequency. More...
 
unsigned get_filter_bw ()
 Get current filter bandwidth. More...
 
double get_gain ()
 Get current gain. More...
 
double get_buffer_level ()
 Get current ringbuffer level (0 = empty . More...
 
std::string get_antenna ()
 Get current antenna port. More...
 
uint32_t rssi ()
 Get RSSI estimate (disabled at the moment) More...
 
double min_gain ()
 
double max_gain ()
 
void enableSampleFileWriting ()
 If sample file creation is enabled, writing samples starts after this call. More...
 
void disableSampleFileWriting ()
 If sample file creation is enabled, writing samples stops after this call. More...
 

Private Member Functions

void init_buffer ()
 
bool set_gain (bool use_agc, double gain, uint8_t idx)
 
bool set_sample_rate (uint32_t rate, uint8_t idx)
 
bool set_filter_bw (uint32_t bandwidth, uint8_t idx)
 
bool set_antenna (const std::string &antenna, uint8_t idx)
 
bool set_frequency (uint32_t frequency, uint8_t idx)
 
void read ()
 

Private Attributes

void * _sdr = nullptr
 
void * _stream = nullptr
 
const libconfig::Config & _cfg
 
std::unique_ptr< MultichannelRingbuffer_buffer
 
std::unique_ptr< MultichannelRingbuffer_buffer_write
 
std::thread _readerThread
 
bool _running
 
unsigned _rx_channels = 1
 
double _sampleRate
 
double _frequency
 
unsigned _filterBw
 
double _gain
 
bool _use_agc
 
double _min_gain
 
double _max_gain
 
std::string _antenna
 
unsigned _overflows
 
unsigned _underflows
 
cf_t * _read_buffer
 
srsran_filesource_t file_source
 
srsran_filesink_t file_sink
 
std::chrono::steady_clock::time_point _last_read
 
bool _high_watermark_reached = false
 
int _sleep_adjustment = 0
 
unsigned _buffer_ms = 200
 
bool _buffer_ready = false
 
bool _reading_from_file = false
 
bool _writing_to_file = false
 
bool _write_samples = false
 
bool _repeat_sample_file = false
 
uint32_t _rssi = 0
 
bool _temp_sensor_available = false
 
std::string _temp_sensor_key = {}
 
std::map< std::string, std::string > _device_args
 

Detailed Description

Interface to the SDR stick.

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

Definition at line 37 of file SdrReader.h.

Constructor & Destructor Documentation

◆ SdrReader()

SdrReader::SdrReader ( const libconfig::Config &  cfg,
size_t  rx_channels 
)
inlineexplicit

Default constructor.

Parameters
cfgConfig singleton reference

Definition at line 44 of file SdrReader.h.

45  : _overflows(0), _underflows(0), _cfg(cfg), _rx_channels(rx_channels), _readerThread{} {}
const libconfig::Config & _cfg
Definition: SdrReader.h:159
std::thread _readerThread
Definition: SdrReader.h:164
unsigned _rx_channels
Definition: SdrReader.h:167
unsigned _overflows
Definition: SdrReader.h:176
unsigned _underflows
Definition: SdrReader.h:177
static Config cfg
Global configuration object.
Definition: main.cpp:172

◆ ~SdrReader()

SdrReader::~SdrReader ( )
virtual

Default destructor.

Definition at line 32 of file SdrReader.cpp.

32  {
33  if (_sdr != nullptr) {
34  auto sdr = (SoapySDR::Device*)_sdr;
35  sdr->deactivateStream((SoapySDR::Stream*)_stream, 0, 0);
36  sdr->closeStream((SoapySDR::Stream*)_stream);
37  SoapySDR::Device::unmake( sdr );
38  }
39 
40  if (_reading_from_file) {
41  srsran_filesource_free(&file_source);
42  }
43 
44  if (_writing_to_file) {
45  srsran_filesink_free(&file_sink);
46  }
47 }
bool _reading_from_file
Definition: SdrReader.h:191
srsran_filesource_t file_source
Definition: SdrReader.h:181
srsran_filesink_t file_sink
Definition: SdrReader.h:182
void * _stream
Definition: SdrReader.h:157
bool _writing_to_file
Definition: SdrReader.h:192
void * _sdr
Definition: SdrReader.h:156

Member Function Documentation

◆ clear_buffer()

void SdrReader::clear_buffer ( )

Clear all samples from the rx buffers.

Definition at line 109 of file SdrReader.cpp.

109  {
110  _buffer->clear();
111  _buffer_write->clear();
112  _high_watermark_reached = false;
113 }
bool _high_watermark_reached
Definition: SdrReader.h:186
std::unique_ptr< MultichannelRingbuffer > _buffer_write
Definition: SdrReader.h:162
std::unique_ptr< MultichannelRingbuffer > _buffer
Definition: SdrReader.h:161

◆ disableSampleFileWriting()

void SdrReader::disableSampleFileWriting ( )
inline

If sample file creation is enabled, writing samples stops after this call.

Definition at line 139 of file SdrReader.h.

139 { _write_samples = false; }
bool _write_samples
Definition: SdrReader.h:193

◆ enableSampleFileWriting()

void SdrReader::enableSampleFileWriting ( )
inline

If sample file creation is enabled, writing samples starts after this call.

Definition at line 134 of file SdrReader.h.

134 { _write_samples = true; }

◆ enumerateDevices()

void SdrReader::enumerateDevices ( )

Prints a list of all available SDR devices.

Definition at line 49 of file SdrReader.cpp.

50 {
51  auto results = SoapySDR::Device::enumerate();
52  SoapySDR::Kwargs::iterator it;
53 
54  for( int i = 0; i < results.size(); ++i)
55  {
56  printf("Device #%d:\n", i);
57  for( it = results[i].begin(); it != results[i].end(); ++it)
58  {
59  printf("%s = %s\n", it->first.c_str(), it->second.c_str());
60  }
61  printf("\n\n");
62  }
63 
64 }

◆ get_antenna()

std::string SdrReader::get_antenna ( )
inline

Get current antenna port.

Definition at line 120 of file SdrReader.h.

120 { return _antenna; }
std::string _antenna
Definition: SdrReader.h:175

◆ get_buffer_level()

auto SdrReader::get_buffer_level ( )

Get current ringbuffer level (0 = empty .

. 1 = full)

Definition at line 399 of file SdrReader.cpp.

400 {
401  if (!_buffer_ready) {
402  return 0;
403  }
404  return static_cast<double>(_buffer->used_size()) / static_cast<double>(_buffer->capacity());
405 }
bool _buffer_ready
Definition: SdrReader.h:190

◆ get_filter_bw()

unsigned SdrReader::get_filter_bw ( )
inline

Get current filter bandwidth.

Definition at line 105 of file SdrReader.h.

105 { return _filterBw; }
unsigned _filterBw
Definition: SdrReader.h:170

◆ get_frequency()

double SdrReader::get_frequency ( )
inline

Get current center frequency.

Definition at line 100 of file SdrReader.h.

100 { return _frequency; }
double _frequency
Definition: SdrReader.h:169

◆ get_gain()

double SdrReader::get_gain ( )
inline

Get current gain.

Definition at line 110 of file SdrReader.h.

110 { return _gain; }
double _gain
Definition: SdrReader.h:171

◆ get_sample_rate()

double SdrReader::get_sample_rate ( )
inline

Get current sample rate.

Definition at line 95 of file SdrReader.h.

95 { return _sampleRate; }
double _sampleRate
Definition: SdrReader.h:168

◆ get_samples()

auto SdrReader::get_samples ( cf_t *  data[SRSRAN_MAX_CHANNELS],
uint32_t  nsamples,
srsran_timestamp_t *  rx_time 
)

Store nsamples count samples into the buffer at data.

Parameters
dataBuffer pointer
nsamplessample count
rx_timeunused

Definition at line 345 of file SdrReader.cpp.

347  {
348  std::chrono::steady_clock::time_point entered = {};
349  entered = std::chrono::steady_clock::now();
350 
351  int64_t required_time_us = (1000000.0/_sampleRate) * nsamples;
352  size_t cnt = nsamples * sizeof(cf_t);
353 
354  if (_high_watermark_reached && _buffer->used_size() < (_sampleRate / 1000.0) * 10 * sizeof(cf_t)) {
355  _high_watermark_reached = false;
356  }
357 
359  while (_buffer->used_size() < (_sampleRate / 1000.0) * (_buffer_ms / 2.0) * sizeof(cf_t)) {
360  std::this_thread::sleep_for(std::chrono::microseconds(500));
361  }
362  spdlog::debug("Filled ringbuffer to half capacity");
364  }
365 
366  std::vector<char*> buffers(_rx_channels);
367  for (auto ch = 0; ch < _rx_channels; ch++) {
368  buffers[ch] = (char*)data[ch];
369  }
370  _buffer->read(buffers, cnt); // Copy from the ringbuffer to the data array. This also decreases _used.
371 
372  if (_buffer->used_size() < (_sampleRate / 1000.0) * (_buffer_ms / 4.0) * sizeof(cf_t)) {
373  required_time_us += 500;
374  } else {
375  required_time_us -= 500;
376  }
377 
378  spdlog::debug("took {}, read {} samples, adjusted required {} us, delta {} us, sleep adj {}, sleeping for {} us",
379  std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - entered).count(),
380  nsamples,
381  std::chrono::microseconds(required_time_us).count(),
382  std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - _last_read).count(),
384  (std::chrono::microseconds(_sleep_adjustment + required_time_us) - std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - _last_read)).count());
385 
386  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));
387 
388  if (sleep.count() > 0) {
389  std::this_thread::sleep_for(sleep);
390  _sleep_adjustment = 0;
391  } else if (sleep.count() > -100000) {
392  _sleep_adjustment = sleep.count();
393  }
394 
395  _last_read = std::chrono::steady_clock::now();
396  return 0;
397 }
int _sleep_adjustment
Definition: SdrReader.h:187
std::chrono::steady_clock::time_point _last_read
Definition: SdrReader.h:184
unsigned _buffer_ms
Definition: SdrReader.h:189

◆ init()

auto SdrReader::init ( const std::string &  device_args,
const char *  sample_file,
const char *  write_sample_file,
bool  repeat_sample_file 
)

Initializes the SDR interface and creates a ring buffer according to the params from Cfg.

Definition at line 66 of file SdrReader.cpp.

67  {
68  if (sample_file != nullptr) {
69  if (0 == srsran_filesource_init(&file_source,
70  const_cast<char*>(sample_file),
71  SRSRAN_COMPLEX_FLOAT_BIN)) {
72  _reading_from_file = true;
73  _repeat_sample_file = repeat_sample_file;
74  } else {
75  spdlog::error("Could not open file {}", sample_file);
76  return false;
77  }
78  } else {
79  if (write_sample_file != nullptr) {
80  if (0 == srsran_filesink_init(&file_sink,
81  const_cast<char*>(write_sample_file),
82  SRSRAN_COMPLEX_FLOAT_BIN)) {
83  _writing_to_file = true;
84  } else {
85  spdlog::error("Could not open file {}", write_sample_file);
86  return false;
87  }
88  }
89  _device_args = SoapySDR::KwargsFromString(device_args);
90  _sdr = SoapySDR::Device::make(_device_args);
91  if (_sdr == nullptr)
92  {
93  spdlog::error("SoapySDR: failed to open device with args {}", device_args);
94  return false;
95  }
96  }
97 
98  _cfg.lookupValue("modem.sdr.ringbuffer_size_ms", _buffer_ms);
99  return true;
100 }
std::map< std::string, std::string > _device_args
Definition: SdrReader.h:201
bool _repeat_sample_file
Definition: SdrReader.h:194

◆ init_buffer()

void SdrReader::init_buffer ( )
private

Definition at line 102 of file SdrReader.cpp.

102  {
103  auto buffer_size = (unsigned int)ceil(_sampleRate/1000.0 * _buffer_ms);
104  _buffer = std::make_unique<MultichannelRingbuffer>(sizeof(cf_t) * buffer_size, _rx_channels);
105  _buffer_write = std::make_unique<MultichannelRingbuffer>(sizeof(cf_t) * buffer_size / 2, _rx_channels); // This is the buffer where we will store the samples to write a big chunk of samples instead many little ones. 1 GB seems to be a sweet amount to write (16e6 * sizeof(cf_t) = 1GB).
106  _buffer_ready = true;
107 }

◆ max_gain()

double SdrReader::max_gain ( )
inline

Definition at line 129 of file SdrReader.h.

129 { return _max_gain; }
double _max_gain
Definition: SdrReader.h:174

◆ min_gain()

double SdrReader::min_gain ( )
inline

Definition at line 127 of file SdrReader.h.

127 { return _min_gain; }
double _min_gain
Definition: SdrReader.h:173

◆ read()

void SdrReader::read ( )
private

Definition at line 268 of file SdrReader.cpp.

268  {
269  std::array<void*, SRSRAN_MAX_CHANNELS> radio_buffers = { nullptr };
270  while (_running) {
271  int toRead = ceil(_sampleRate / 1000.0);
272  //int toRead = 254;
273  if (_buffer->free_size() < toRead * sizeof(cf_t)) {
274  spdlog::debug("ringbuffer overflow");
275  std::this_thread::sleep_for(std::chrono::microseconds(1000));
276  } else {
277  int read = 0;
278  size_t writeable = 0;
279  size_t writeable_write = 0;
280  auto buffers = _buffer->write_head(&writeable);
281  auto buffers_write = _buffer_write->write_head(&writeable_write);
282  int writeable_samples = (int)floor(writeable / sizeof(cf_t));
283  int writeable_write_samples = (int)floor(writeable_write / sizeof(cf_t));
284 
285  if (_reading_from_file) {
286  std::chrono::steady_clock::time_point entered = {};
287  entered = std::chrono::steady_clock::now();
288 
289  read = srsran_filesource_read_multi(&file_source, buffers.data(), std::min(writeable_samples, toRead), (int)_rx_channels);
290  if ( read == 0 ) {
291  if (_repeat_sample_file) {
292  srsran_filesource_seek(&file_source, 0);
293  } else {
294  spdlog::info("EOF, exiting...");
295  raise(SIGINT); //SIGINT to signal srsran that we want to exit.
296  }
297  }
298  read = read / _rx_channels;
299  int64_t required_time_us = (1000000.0/_sampleRate) * read;
300 
301  if (read > 0) {
302  _buffer->commit( read * sizeof(cf_t) );
303  }
304 
305  std::chrono::microseconds sleep = (std::chrono::microseconds(required_time_us) -
306  std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - entered));
307  std::this_thread::sleep_for(sleep);
308  } else {
309  auto sdr = (SoapySDR::Device*)_sdr;
310  int flags = 0;
311  long long time_ns = 0;
312  auto rbuff = buffers.data();
313  auto wbuff = buffers_write.data();
314 
315  read = sdr->readStream( (SoapySDR::Stream*)_stream, buffers.data(), std::min(writeable_samples, toRead), flags, time_ns);
316 
317  if (read> 0 ) {
318 
319  if (_writing_to_file && _write_samples && writeable_write_samples) { // Only if we are going to write into a file.
320  for (int i = 0; i < _rx_channels; i++) {
321  memcpy(wbuff[i], rbuff[i], std::min(writeable_write_samples, read) * sizeof(cf_t)); // Copy the data in the input buffer to the toWrite buffer.
322  }
323  _buffer_write->commit( std::min(writeable_write_samples, read) * sizeof(cf_t)); // We used another ring buffer for the written of the samples, to not block a lot we only write to the disk when the ring buffer is at 90% of its capacity
324  }
325  _buffer->commit( read * sizeof(cf_t) );
326 
327  if (_writing_to_file && _write_samples && _buffer_write->used_size() >= 0.90* _buffer_write->capacity()) {
328  int toWrite_samples = _buffer_write->used_size() / sizeof(cf_t); // We are going to storage all the info
329  auto buff_to_write = _buffer_write->read_head(); // Gives the beggining of the buffer, it also puts _used and _head to 0, to start adding at the beggining again.
330  srsran_filesink_write_multi(&file_sink, buff_to_write.data(), toWrite_samples, (int)_rx_channels); // From the beggining of the buffer we write used_size data
331  }
332  spdlog::debug("buffer: commited {}, requested {}, writeable {}, writeable_write {}, flags {}", read, toRead, writeable_samples, writeable_write_samples, flags);
333  }
334  else {
335  spdlog::error("readStream returned {}", read);
336  _buffer->commit( toRead * sizeof(cf_t) );
337  _buffer_write->commit(toRead * sizeof(cf_t));
338  }
339  }
340  }
341  }
342  spdlog::debug("Sample reader thread exited");
343 }
bool _running
Definition: SdrReader.h:165
void read()
Definition: SdrReader.cpp:268

◆ rssi()

uint32_t SdrReader::rssi ( )
inline

Get RSSI estimate (disabled at the moment)

Definition at line 125 of file SdrReader.h.

125 { return _rssi; }
uint32_t _rssi
Definition: SdrReader.h:196

◆ set_antenna()

auto SdrReader::set_antenna ( const std::string &  antenna,
uint8_t  idx 
)
private

Definition at line 115 of file SdrReader.cpp.

115  {
116  auto sdr = (SoapySDR::Device*)_sdr;
117  auto antenna_list = sdr->listAntennas(SOAPY_SDR_RX, idx);
118  if (std::find(antenna_list.begin(), antenna_list.end(), antenna) != antenna_list.end()) {
119  sdr->setAntenna( SOAPY_SDR_RX, idx, antenna);
120  _antenna = sdr->getAntenna( SOAPY_SDR_RX, idx);
121  return true;
122  } else {
123  spdlog::error("Unknown antenna \"{}\". Available: {}.", antenna, boost::algorithm::join(antenna_list, ", ") );
124  return false;
125  }
126 }
static std::string antenna
Antenna input to be used.
Definition: main.cpp:179

◆ set_filter_bw()

auto SdrReader::set_filter_bw ( uint32_t  bandwidth,
uint8_t  idx 
)
private

Definition at line 134 of file SdrReader.cpp.

134  {
135  auto sdr = (SoapySDR::Device*)_sdr;
136  sdr->setBandwidth( SOAPY_SDR_RX, idx, bandwidth);
137  return true;
138 }
static uint32_t bandwidth
Low pass filter bandwidth for the SDR.
Definition: main.cpp:177

◆ set_frequency()

auto SdrReader::set_frequency ( uint32_t  frequency,
uint8_t  idx 
)
private

Definition at line 128 of file SdrReader.cpp.

128  {
129  auto sdr = (SoapySDR::Device*)_sdr;
130  sdr->setFrequency( SOAPY_SDR_RX, idx, frequency);
131  return true;
132 }
static unsigned frequency
Center freqeuncy the SDR is tuned to.
Definition: main.cpp:176

◆ set_gain()

auto SdrReader::set_gain ( bool  use_agc,
double  gain,
uint8_t  idx 
)
private

Definition at line 146 of file SdrReader.cpp.

146  {
147  auto sdr = (SoapySDR::Device*)_sdr;
148  if (sdr->hasGainMode(SOAPY_SDR_RX, idx)) {
149 // spdlog::info("{} AGC", use_agc ? "Enabling" : "Disabling");
150  sdr->setGainMode(SOAPY_SDR_RX, idx, use_agc);
151  } else if (use_agc) {
152 // spdlog::info("AGC is not supported by this device, please set gain manually");
153  }
154  auto gain_range = sdr->getGainRange(SOAPY_SDR_RX, idx);
155  _min_gain = gain_range.minimum();
156  _max_gain = gain_range.maximum();
157  if (gain >= gain_range.minimum() && gain <= gain_range.maximum()) {
158  sdr->setGain( SOAPY_SDR_RX, idx, gain);
159  if (idx == 0) {
160  _gain = sdr->getGain( SOAPY_SDR_RX, idx);
161  }
162  return true;
163  } else {
164  spdlog::error("Invalid gain setting {}. Allowed range is: {} - {}.", gain, gain_range.minimum(), gain_range.maximum());
165  return false;
166  }
167 }
static bool use_agc
Definition: main.cpp:180
static double gain
Overall system gain for the SDR.
Definition: main.cpp:178

◆ set_sample_rate()

auto SdrReader::set_sample_rate ( uint32_t  rate,
uint8_t  idx 
)
private

Definition at line 140 of file SdrReader.cpp.

140  {
141  auto sdr = (SoapySDR::Device*)_sdr;
142  sdr->setSampleRate( SOAPY_SDR_RX, idx, rate);
143  return true;
144 }

◆ start()

void SdrReader::start ( )

Start reading samples from the SDR.

Definition at line 216 of file SdrReader.cpp.

216  {
217  if (_sdr != nullptr) {
218  auto sdr = (SoapySDR::Device*)_sdr;
219  std::vector<size_t> channels(_rx_channels);
220  for (auto ch = 0; ch < _rx_channels; ch++) {
221  channels[ch] = ch;
222  }
223  sdr->setHardwareTime(0); // Set SDR timestamp to zero.
224  _stream = sdr->setupStream( SOAPY_SDR_RX, SOAPY_SDR_CF32, channels, _device_args);
225  if( _stream == nullptr)
226  {
227  spdlog::error("Failed to set up RX stream");
228  SoapySDR::Device::unmake( sdr );
229  return ;
230  }
231  sdr->activateStream( (SoapySDR::Stream*)_stream, SOAPY_SDR_HAS_TIME, 100000000, 0); // Delayed start of the SDR reception, to avoid overfloas at the beggining.
232  }
233  _running = true;
234 
235  // Start the reader thread and elevate its priority to realtime
236  _readerThread = std::thread{&SdrReader::read, this};
237  struct sched_param thread_param = {};
238  thread_param.sched_priority = 50;
239  int min_prio = sched_get_priority_min(SCHED_RR);
240  int max_prio = sched_get_priority_max(SCHED_RR);
241 
242  if (min_prio == -1 or max_prio == -1)
243  spdlog::error("Something went wrong, error in sched_get_priority_min/max");
244 
245  _cfg.lookupValue("modem.sdr.reader_thread_priority_rt", thread_param.sched_priority);
246 
247  spdlog::debug("Launching sample reader thread with realtime scheduling priority {}, available priorities, max: {}, min: {}", thread_param.sched_priority, max_prio, min_prio);
248 
249  int error = pthread_setschedparam(_readerThread.native_handle(), SCHED_RR, &thread_param);
250  if (error != 0) {
251  spdlog::warn("Cannot set reader thread priority to realtime: {}. Thread will run at default priority with a high probability of dropped samples and loss of synchronisation.", strerror(error));
252  }
253 }

◆ stop()

void SdrReader::stop ( )

Stop reading samples from the SDR.

Definition at line 255 of file SdrReader.cpp.

255  {
256  _running = false;
257 
258  _readerThread.join();
259  if (_sdr != nullptr) {
260  auto sdr = (SoapySDR::Device*)_sdr;
261  sdr->deactivateStream((SoapySDR::Stream*)_stream, 0, 0);
262  sdr->closeStream((SoapySDR::Stream*)_stream);
263  }
264 
265  clear_buffer();
266 }
void clear_buffer()
Clear all samples from the rx buffers.
Definition: SdrReader.cpp:109

◆ tune()

auto SdrReader::tune ( uint32_t  frequency,
uint32_t  sample_rate,
uint32_t  bandwidth,
double  gain,
const std::string &  antenna,
bool  use_agc 
)

Tune the SDR to the desired frequency, and set gain, filter and antenna parameters.

Definition at line 169 of file SdrReader.cpp.

170  {
174  _use_agc = use_agc;
175 
176  init_buffer();
177 
178  if (_reading_from_file) {
179  return true;
180  }
181 
182  if (_sdr == nullptr) {
183  return false;
184  }
185 
186  spdlog::info("Tuning to {} MHz, filter bandwidth {} MHz, sample rate {}, gain {}, antenna path {} with AGC set to {}",
187  frequency/1000000.0, bandwidth/1000000.0, sample_rate/1000000.0, gain, antenna, use_agc);
188 
189  auto sdr = (SoapySDR::Device*)_sdr;
190 
191  for (auto ch = 0; ch < _rx_channels; ch++) {
192  set_antenna(antenna, ch);
193  set_gain(_use_agc, gain, ch);
197  }
198 
199  _frequency = sdr->getFrequency( SOAPY_SDR_RX, 0);
200  bandwidth = sdr->getBandwidth( SOAPY_SDR_RX, 0);
201  _sampleRate = sdr->getSampleRate( SOAPY_SDR_RX, 0);
202 
203  spdlog::info("SDR tuned to {} MHz, filter bandwidth {} MHz, sample rate {}, gain {}, antenna path {}",
204  _frequency/1000000.0, bandwidth/1000000.0, _sampleRate/1000000.0, _gain, _antenna);
205 
206 
207  auto sensors = sdr->listSensors();
208  if (std::find(sensors.begin(), sensors.end(), "lms7_temp") != sensors.end()) {
209  _temp_sensor_available = true;
210  _temp_sensor_key = "lms7_temp";
211  }
212 
213  return true;
214 }
std::string _temp_sensor_key
Definition: SdrReader.h:199
bool set_gain(bool use_agc, double gain, uint8_t idx)
Definition: SdrReader.cpp:146
bool set_sample_rate(uint32_t rate, uint8_t idx)
Definition: SdrReader.cpp:140
bool set_antenna(const std::string &antenna, uint8_t idx)
Definition: SdrReader.cpp:115
void init_buffer()
Definition: SdrReader.cpp:102
bool _use_agc
Definition: SdrReader.h:172
bool set_filter_bw(uint32_t bandwidth, uint8_t idx)
Definition: SdrReader.cpp:134
bool _temp_sensor_available
Definition: SdrReader.h:198
bool set_frequency(uint32_t frequency, uint8_t idx)
Definition: SdrReader.cpp:128
static unsigned sample_rate
Sample rate of the SDR.
Definition: main.cpp:174

Member Data Documentation

◆ _antenna

std::string SdrReader::_antenna
private

Definition at line 175 of file SdrReader.h.

◆ _buffer

std::unique_ptr<MultichannelRingbuffer> SdrReader::_buffer
private

Definition at line 161 of file SdrReader.h.

◆ _buffer_ms

unsigned SdrReader::_buffer_ms = 200
private

Definition at line 189 of file SdrReader.h.

◆ _buffer_ready

bool SdrReader::_buffer_ready = false
private

Definition at line 190 of file SdrReader.h.

◆ _buffer_write

std::unique_ptr<MultichannelRingbuffer> SdrReader::_buffer_write
private

Definition at line 162 of file SdrReader.h.

◆ _cfg

const libconfig::Config& SdrReader::_cfg
private

Definition at line 159 of file SdrReader.h.

◆ _device_args

std::map<std::string, std::string> SdrReader::_device_args
private

Definition at line 201 of file SdrReader.h.

◆ _filterBw

unsigned SdrReader::_filterBw
private

Definition at line 170 of file SdrReader.h.

◆ _frequency

double SdrReader::_frequency
private

Definition at line 169 of file SdrReader.h.

◆ _gain

double SdrReader::_gain
private

Definition at line 171 of file SdrReader.h.

◆ _high_watermark_reached

bool SdrReader::_high_watermark_reached = false
private

Definition at line 186 of file SdrReader.h.

◆ _last_read

std::chrono::steady_clock::time_point SdrReader::_last_read
private

Definition at line 184 of file SdrReader.h.

◆ _max_gain

double SdrReader::_max_gain
private

Definition at line 174 of file SdrReader.h.

◆ _min_gain

double SdrReader::_min_gain
private

Definition at line 173 of file SdrReader.h.

◆ _overflows

unsigned SdrReader::_overflows
private

Definition at line 176 of file SdrReader.h.

◆ _read_buffer

cf_t* SdrReader::_read_buffer
private

Definition at line 179 of file SdrReader.h.

◆ _readerThread

std::thread SdrReader::_readerThread
private

Definition at line 164 of file SdrReader.h.

◆ _reading_from_file

bool SdrReader::_reading_from_file = false
private

Definition at line 191 of file SdrReader.h.

◆ _repeat_sample_file

bool SdrReader::_repeat_sample_file = false
private

Definition at line 194 of file SdrReader.h.

◆ _rssi

uint32_t SdrReader::_rssi = 0
private

Definition at line 196 of file SdrReader.h.

◆ _running

bool SdrReader::_running
private

Definition at line 165 of file SdrReader.h.

◆ _rx_channels

unsigned SdrReader::_rx_channels = 1
private

Definition at line 167 of file SdrReader.h.

◆ _sampleRate

double SdrReader::_sampleRate
private

Definition at line 168 of file SdrReader.h.

◆ _sdr

void* SdrReader::_sdr = nullptr
private

Definition at line 156 of file SdrReader.h.

◆ _sleep_adjustment

int SdrReader::_sleep_adjustment = 0
private

Definition at line 187 of file SdrReader.h.

◆ _stream

void* SdrReader::_stream = nullptr
private

Definition at line 157 of file SdrReader.h.

◆ _temp_sensor_available

bool SdrReader::_temp_sensor_available = false
private

Definition at line 198 of file SdrReader.h.

◆ _temp_sensor_key

std::string SdrReader::_temp_sensor_key = {}
private

Definition at line 199 of file SdrReader.h.

◆ _underflows

unsigned SdrReader::_underflows
private

Definition at line 177 of file SdrReader.h.

◆ _use_agc

bool SdrReader::_use_agc
private

Definition at line 172 of file SdrReader.h.

◆ _write_samples

bool SdrReader::_write_samples = false
private

Definition at line 193 of file SdrReader.h.

◆ _writing_to_file

bool SdrReader::_writing_to_file = false
private

Definition at line 192 of file SdrReader.h.

◆ file_sink

srsran_filesink_t SdrReader::file_sink
private

Definition at line 182 of file SdrReader.h.

◆ file_source

srsran_filesource_t SdrReader::file_source
private

Definition at line 181 of file SdrReader.h.


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