diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/DabMod.cpp | 4 | ||||
-rw-r--r-- | src/DabModulator.cpp | 34 | ||||
-rw-r--r-- | src/DabModulator.h | 21 | ||||
-rw-r--r-- | src/GainControl.h | 2 | ||||
-rw-r--r-- | src/RemoteControl.cpp | 94 | ||||
-rw-r--r-- | src/RemoteControl.h | 50 | ||||
-rw-r--r-- | src/TimestampDecoder.cpp | 24 | ||||
-rw-r--r-- | src/TimestampDecoder.h | 17 | ||||
-rw-r--r-- | src/output/SDR.cpp | 10 | ||||
-rw-r--r-- | src/output/Soapy.cpp | 6 |
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 ¶m : 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 ¶m_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 ¶m_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 ¶m : 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"; |