summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DabMod.cpp4
-rw-r--r--src/DabModulator.cpp34
-rw-r--r--src/DabModulator.h21
-rw-r--r--src/GainControl.h2
-rw-r--r--src/RemoteControl.cpp94
-rw-r--r--src/RemoteControl.h50
-rw-r--r--src/TimestampDecoder.cpp24
-rw-r--r--src/TimestampDecoder.h17
-rw-r--r--src/output/SDR.cpp10
-rw-r--r--src/output/Soapy.cpp6
10 files changed, 158 insertions, 104 deletions
diff --git a/src/DabMod.cpp b/src/DabMod.cpp
index a217bfe..3806048 100644
--- a/src/DabMod.cpp
+++ b/src/DabMod.cpp
@@ -3,7 +3,7 @@
Her Majesty the Queen in Right of Canada (Communications Research
Center Canada)
- Copyright (C) 2018
+ Copyright (C) 2019
Matthias P. Braendli, matthias.braendli@mpb.li
http://opendigitalradio.org
@@ -335,6 +335,7 @@ int launch_modulator(int argc, char* argv[])
Flowgraph flowgraph;
auto modulator = make_shared<DabModulator>(ediReader, mod_settings);
+ rcs.enrol(modulator.get());
if (format_converter) {
flowgraph.connect(modulator, format_converter);
@@ -440,6 +441,7 @@ int launch_modulator(int argc, char* argv[])
auto input = make_shared<InputMemory>(&m.data);
auto modulator = make_shared<DabModulator>(etiReader, mod_settings);
+ rcs.enrol(modulator.get());
if (format_converter) {
flowgraph.connect(modulator, format_converter);
diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp
index ca958e3..666745d 100644
--- a/src/DabModulator.cpp
+++ b/src/DabModulator.cpp
@@ -3,7 +3,7 @@
Her Majesty the Queen in Right of Canada (Communications Research
Center Canada)
- Copyright (C) 2018
+ Copyright (C) 2019
Matthias P. Braendli, matthias.braendli@mpb.li
http://opendigitalradio.org
@@ -58,15 +58,20 @@
#include "RemoteControl.h"
#include "Log.h"
+using namespace std;
+
DabModulator::DabModulator(EtiSource& etiSource,
mod_settings_t& settings) :
ModInput(),
+ RemoteControllable("modulator"),
m_settings(settings),
myEtiSource(etiSource),
myFlowgraph()
{
PDEBUG("DabModulator::DabModulator() @ %p\n", this);
+ RC_ADD_PARAMETER(rate, "(Read-only) IQ output samplerate");
+
if (m_settings.dabMode == 0) {
setMode(2);
}
@@ -385,3 +390,30 @@ meta_vec_t DabModulator::process_metadata(const meta_vec_t& metadataIn)
return {};
}
+
+void DabModulator::set_parameter(const string& parameter, const string& value)
+{
+ if (parameter == "rate") {
+ throw ParameterError("Parameter 'rate' is read-only");
+ }
+ else {
+ stringstream ss;
+ ss << "Parameter '" << parameter <<
+ "' is not exported by controllable " << get_rc_name();
+ throw ParameterError(ss.str());
+ }
+}
+
+const string DabModulator::get_parameter(const string& parameter) const
+{
+ stringstream ss;
+ if (parameter == "rate") {
+ ss << m_settings.outputRate;
+ }
+ else {
+ ss << "Parameter '" << parameter <<
+ "' is not exported by controllable " << get_rc_name();
+ throw ParameterError(ss.str());
+ }
+ return ss.str();
+}
diff --git a/src/DabModulator.h b/src/DabModulator.h
index 355eeb3..00d71f5 100644
--- a/src/DabModulator.h
+++ b/src/DabModulator.h
@@ -3,7 +3,7 @@
Her Majesty the Queen in Right of Canada (Communications Research
Center Canada)
- Copyright (C) 2018
+ Copyright (C) 2019
Matthias P. Braendli, matthias.braendli@mpb.li
http://opendigitalradio.org
@@ -46,21 +46,26 @@
#include "TII.h"
-class DabModulator : public ModInput, public ModMetadata
+class DabModulator : public ModInput, public ModMetadata, public RemoteControllable
{
public:
- DabModulator(EtiSource& etiSource,
- mod_settings_t& settings);
+ DabModulator(EtiSource& etiSource, mod_settings_t& settings);
- int process(Buffer* dataOut);
- const char* name() { return "DabModulator"; }
+ int process(Buffer* dataOut) override;
+ const char* name() override { return "DabModulator"; }
- virtual meta_vec_t process_metadata(
- const meta_vec_t& metadataIn);
+ virtual meta_vec_t process_metadata(const meta_vec_t& metadataIn) override;
/* Required to get the timestamp */
EtiSource* getEtiSource() { return &myEtiSource; }
+ /******* REMOTE CONTROL ********/
+ virtual void set_parameter(const std::string& parameter,
+ const std::string& value) override;
+
+ virtual const std::string get_parameter(
+ const std::string& parameter) const override;
+
protected:
void setMode(unsigned mode);
diff --git a/src/GainControl.h b/src/GainControl.h
index e8965e9..4c9a2bc 100644
--- a/src/GainControl.h
+++ b/src/GainControl.h
@@ -76,7 +76,7 @@ class GainControl : public PipelinedModCodec, public RemoteControllable
Buffer* const dataIn, Buffer* dataOut) override;
size_t m_frameSize;
- float m_digGain;
+ float& m_digGain;
float m_normalise;
// The following variables are accessed from the RC thread
diff --git a/src/RemoteControl.cpp b/src/RemoteControl.cpp
index 3c27279..808153a 100644
--- a/src/RemoteControl.cpp
+++ b/src/RemoteControl.cpp
@@ -3,7 +3,7 @@
Her Majesty the Queen in Right of Canada (Communications Research
Center Canada)
- Copyright (C) 2018
+ Copyright (C) 2019
Matthias P. Braendli, matthias.braendli@mpb.li
http://www.opendigitalradio.org
@@ -76,8 +76,53 @@ std::list<std::string> RemoteControllable::get_supported_parameters() const {
return parameterlist;
}
-RemoteControllable* RemoteControllers::get_controllable_(
- const std::string& name)
+void RemoteControllers::add_controller(std::shared_ptr<BaseRemoteController> rc) {
+ m_controllers.push_back(rc);
+}
+
+void RemoteControllers::enrol(RemoteControllable *rc) {
+ controllables.push_back(rc);
+}
+
+void RemoteControllers::remove_controllable(RemoteControllable *rc) {
+ controllables.remove(rc);
+}
+
+std::list< std::vector<std::string> > RemoteControllers::get_param_list_values(const std::string& name) {
+ RemoteControllable* controllable = get_controllable_(name);
+
+ std::list< std::vector<std::string> > allparams;
+ for (auto &param : controllable->get_supported_parameters()) {
+ std::vector<std::string> item;
+ item.push_back(param);
+ try {
+ item.push_back(controllable->get_parameter(param));
+ }
+ catch (const ParameterError &e) {
+ item.push_back(std::string("error: ") + e.what());
+ }
+
+ allparams.push_back(item);
+ }
+ return allparams;
+}
+
+std::string RemoteControllers::get_param(const std::string& name, const std::string& param) {
+ RemoteControllable* controllable = get_controllable_(name);
+ return controllable->get_parameter(param);
+}
+
+void RemoteControllers::check_faults() {
+ for (auto &controller : m_controllers) {
+ if (controller->fault_detected()) {
+ etiLog.level(warn) <<
+ "Detected Remote Control fault, restarting it";
+ controller->restart();
+ }
+ }
+}
+
+RemoteControllable* RemoteControllers::get_controllable_(const std::string& name)
{
auto rc = std::find_if(controllables.begin(), controllables.end(),
[&](RemoteControllable* r) { return r->get_rc_name() == name; });
@@ -183,7 +228,7 @@ void RemoteControllerTelnet::handle_accept(
etiLog.level(info) << "RC: Closing socket";
socket->close();
}
- catch (std::exception& e)
+ catch (const std::exception& e)
{
etiLog.level(error) << "Remote control caught exception: " << e.what();
}
@@ -279,7 +324,7 @@ void RemoteControllerTelnet::dispatch_command(tcp::socket& socket, string comman
reply(socket, ss.str());
}
- catch (ParameterError &e) {
+ catch (const ParameterError &e) {
reply(socket, e.what());
}
}
@@ -293,7 +338,7 @@ void RemoteControllerTelnet::dispatch_command(tcp::socket& socket, string comman
string r = rcs.get_param(cmd[1], cmd[2]);
reply(socket, r);
}
- catch (ParameterError &e) {
+ catch (const ParameterError &e) {
reply(socket, e.what());
}
}
@@ -316,10 +361,10 @@ void RemoteControllerTelnet::dispatch_command(tcp::socket& socket, string comman
rcs.set_param(cmd[1], cmd[2], new_param_value.str());
reply(socket, "ok");
}
- catch (ParameterError &e) {
+ catch (const ParameterError &e) {
reply(socket, e.what());
}
- catch (exception &e) {
+ catch (const exception &e) {
reply(socket, "Error: Invalid parameter value. ");
}
}
@@ -478,21 +523,16 @@ void RemoteControllerZmq::process()
}
else if (msg.size() == 2 && command == "show") {
std::string module((char*) msg[1].data(), msg[1].size());
- try {
- list< vector<string> > r = rcs.get_param_list_values(module);
- size_t r_size = r.size();
- for (auto &param_val : r) {
- std::stringstream ss;
- ss << param_val[0] << ": " << param_val[1] << endl;
- zmq::message_t zmsg(ss.str().size());
- memcpy(zmsg.data(), ss.str().data(), ss.str().size());
-
- int flag = (--r_size > 0) ? ZMQ_SNDMORE : 0;
- repSocket.send(zmsg, flag);
- }
- }
- catch (ParameterError &e) {
- send_fail_reply(repSocket, e.what());
+ list< vector<string> > r = rcs.get_param_list_values(module);
+ size_t r_size = r.size();
+ for (auto &param_val : r) {
+ std::stringstream ss;
+ ss << param_val[0] << ": " << param_val[1] << endl;
+ zmq::message_t zmsg(ss.str().size());
+ memcpy(zmsg.data(), ss.str().data(), ss.str().size());
+
+ int flag = (--r_size > 0) ? ZMQ_SNDMORE : 0;
+ repSocket.send(zmsg, flag);
}
}
else if (msg.size() == 3 && command == "get") {
@@ -505,7 +545,7 @@ void RemoteControllerZmq::process()
memcpy ((void*) zmsg.data(), value.data(), value.size());
repSocket.send(zmsg, 0);
}
- catch (ParameterError &err) {
+ catch (const ParameterError &err) {
send_fail_reply(repSocket, err.what());
}
}
@@ -518,7 +558,7 @@ void RemoteControllerZmq::process()
rcs.set_param(module, parameter, value);
send_ok_reply(repSocket);
}
- catch (ParameterError &err) {
+ catch (const ParameterError &err) {
send_fail_reply(repSocket, err.what());
}
}
@@ -530,10 +570,10 @@ void RemoteControllerZmq::process()
}
repSocket.close();
}
- catch (zmq::error_t &e) {
+ catch (const zmq::error_t &e) {
etiLog.level(error) << "ZMQ RC error: " << std::string(e.what());
}
- catch (std::exception& e) {
+ catch (const std::exception& e) {
etiLog.level(error) << "ZMQ RC caught exception: " << e.what();
m_fault = true;
}
diff --git a/src/RemoteControl.h b/src/RemoteControl.h
index 733ee2d..087b94a 100644
--- a/src/RemoteControl.h
+++ b/src/RemoteControl.h
@@ -3,7 +3,7 @@
Her Majesty the Queen in Right of Canada (Communications Research
Center Canada)
- Copyright (C) 2018
+ Copyright (C) 2019
Matthias P. Braendli, matthias.braendli@mpb.li
http://www.opendigitalradio.org
@@ -131,48 +131,12 @@ class RemoteControllable {
*/
class RemoteControllers {
public:
- void add_controller(std::shared_ptr<BaseRemoteController> rc) {
- m_controllers.push_back(rc);
- }
-
- void enrol(RemoteControllable *rc) {
- controllables.push_back(rc);
- }
-
- void remove_controllable(RemoteControllable *rc) {
- controllables.remove(rc);
- }
-
- void check_faults() {
- for (auto &controller : m_controllers) {
- if (controller->fault_detected())
- {
- etiLog.level(warn) <<
- "Detected Remote Control fault, restarting it";
- controller->restart();
- }
- }
- }
-
- std::list< std::vector<std::string> >
- get_param_list_values(const std::string& name) {
- RemoteControllable* controllable = get_controllable_(name);
-
- std::list< std::vector<std::string> > allparams;
- for (auto &param : controllable->get_supported_parameters()) {
- std::vector<std::string> item;
- item.push_back(param);
- item.push_back(controllable->get_parameter(param));
-
- allparams.push_back(item);
- }
- return allparams;
- }
-
- std::string get_param(const std::string& name, const std::string& param) {
- RemoteControllable* controllable = get_controllable_(name);
- return controllable->get_parameter(param);
- }
+ void add_controller(std::shared_ptr<BaseRemoteController> rc);
+ void enrol(RemoteControllable *rc);
+ void remove_controllable(RemoteControllable *rc);
+ void check_faults();
+ std::list< std::vector<std::string> > get_param_list_values(const std::string& name);
+ std::string get_param(const std::string& name, const std::string& param);
void set_param(
const std::string& name,
diff --git a/src/TimestampDecoder.cpp b/src/TimestampDecoder.cpp
index 4aaaf67..a561237 100644
--- a/src/TimestampDecoder.cpp
+++ b/src/TimestampDecoder.cpp
@@ -35,6 +35,28 @@
//#define MDEBUG(fmt, args...) fprintf (LOG, "*****" fmt , ## args)
#define MDEBUG(fmt, args...) PDEBUG(fmt, ## args)
+frame_timestamp& frame_timestamp::operator+=(const double& diff)
+{
+ double offset_pps, offset_secs;
+ offset_pps = modf(diff, &offset_secs);
+
+ this->timestamp_sec += lrint(offset_secs);
+ int64_t new_pps = (int64_t)this->timestamp_pps + llrint(offset_pps * 16384000.0);
+
+ while (new_pps < 0) {
+ this->timestamp_sec -= 1;
+ new_pps += 16384000;
+ }
+
+ while (new_pps > 16384000) {
+ this->timestamp_sec += 1;
+ new_pps -= 16384000;
+ }
+
+ this->timestamp_pps = new_pps;
+ return *this;
+}
+
TimestampDecoder::TimestampDecoder(double& offset_s) :
RemoteControllable("tist"),
timestamp_offset(offset_s)
@@ -65,8 +87,6 @@ std::shared_ptr<frame_timestamp> TimestampDecoder::getTimestamp()
ts->timestamp_refresh = offset_changed;
offset_changed = false;
- MDEBUG("time_secs=%d, time_pps=%f\n", time_secs,
- (double)time_pps / 16384000.0);
*ts += timestamp_offset;
return ts;
diff --git a/src/TimestampDecoder.h b/src/TimestampDecoder.h
index ed41dfb..d083061 100644
--- a/src/TimestampDecoder.h
+++ b/src/TimestampDecoder.h
@@ -44,22 +44,9 @@ struct frame_timestamp
bool timestamp_valid = false;
bool timestamp_refresh;
- frame_timestamp& operator+=(const double& diff)
- {
- double offset_pps, offset_secs;
- offset_pps = modf(diff, &offset_secs);
-
- this->timestamp_sec += lrint(offset_secs);
- this->timestamp_pps += lrint(offset_pps * 16384000.0);
-
- while (this->timestamp_pps >= 16384000) {
- this->timestamp_pps -= 16384000;
- this->timestamp_sec += 1;
- }
- return *this;
- }
+ frame_timestamp& operator+=(const double& diff);
- const frame_timestamp operator+(const double diff) {
+ const frame_timestamp operator+(const double diff) const {
frame_timestamp ts = *this;
ts += diff;
return ts;
diff --git a/src/output/SDR.cpp b/src/output/SDR.cpp
index 068b5af..23a947b 100644
--- a/src/output/SDR.cpp
+++ b/src/output/SDR.cpp
@@ -66,10 +66,12 @@ SDR::SDR(SDRDeviceConfig& config, std::shared_ptr<SDRDevice> device) :
m_device_thread = std::thread(&SDR::process_thread_entry, this);
- m_dpd_feedback_server = make_shared<DPDFeedbackServer>(
- m_device,
- m_config.dpdFeedbackServerPort,
- m_config.sampleRate);
+ if (m_config.dpdFeedbackServerPort > 0) {
+ m_dpd_feedback_server = make_shared<DPDFeedbackServer>(
+ m_device,
+ m_config.dpdFeedbackServerPort,
+ m_config.sampleRate);
+ }
RC_ADD_PARAMETER(txgain, "TX gain");
RC_ADD_PARAMETER(rxgain, "RX gain for DPD feedback");
diff --git a/src/output/Soapy.cpp b/src/output/Soapy.cpp
index 86ed3e0..8c84b84 100644
--- a/src/output/Soapy.cpp
+++ b/src/output/Soapy.cpp
@@ -71,8 +71,10 @@ Soapy::Soapy(SDRDeviceConfig& config) :
throw std::runtime_error("Cannot create SoapySDR output");
}
- m_device->setMasterClockRate(m_conf.masterClockRate);
- etiLog.level(info) << "SoapySDR master clock rate set to " <<
+ if (m_conf.masterClockRate != 0) {
+ m_device->setMasterClockRate(m_conf.masterClockRate);
+ }
+ etiLog.level(info) << "SoapySDR:Actual master clock rate: " <<
std::fixed << std::setprecision(4) <<
m_device->getMasterClockRate()/1000.0 << " kHz";