Tuner config support

This commit is contained in:
Ezra Taimuty-Loomis 2021-02-12 13:38:45 -05:00
parent b1b5660a08
commit 31fe3cc2d8
4 changed files with 123 additions and 23 deletions

View File

@ -40,7 +40,7 @@ Configuration& Configuration::getConfig() {
Configuration::Configuration() : _generalConfig(*this, path::config_base_path),
_socketConfig(*this, path::config_base_path), _demodConfig(*this, path::config_base_path),
_rtspConfig(*this, path::config_base_path) {
_rtspConfig(*this, path::config_base_path), _tunerList(*this, path::config_base_path) {
_configPath = DATABASE_PATH;
}
@ -104,7 +104,7 @@ void Configuration::loadAll(){
_socketConfig.load();
_demodConfig.load();
_rtspConfig.load();
_tunerList.load();
}
void Configuration::saveAll(){
@ -112,6 +112,7 @@ void Configuration::saveAll(){
_socketConfig.save();
_demodConfig.save();
_rtspConfig.save();
_tunerList.save();
}
std::string Configuration::getLogDirectory(){
@ -156,6 +157,8 @@ void Configuration::invalidate() {
}
/* Config implementations */
GeneralConfig::GeneralConfig(ConfigManager& cm, std::string path) : ConfigBase(cm, std::move(path)) {};
void GeneralConfig::load() {
logfileVerbosity = base.pTree().get(basePath + path::path_seperator + "general" + path::path_seperator + "log_verbosity", DEFAULT_LOGFILE_VERBOSITY);
}
@ -165,6 +168,8 @@ void GeneralConfig::save() {
base.invalidate();
}
SocketServerConfig::SocketServerConfig(ConfigManager& cm, std::string path) : ConfigBase(cm, std::move(path)) {};
void SocketServerConfig::load() {
maxConnections = base.pTree().get(basePath + path::path_seperator + "socket" + path::path_seperator + "max_connections", MAX_TCP_CONNECTIONS);
tcpPort = base.pTree().get(basePath + path::path_seperator + "socket" + path::path_seperator + "port", DEFAULT_TCP_PORT);
@ -181,6 +186,8 @@ void SocketServerConfig::save() {
base.pTree().put(basePath + path::path_seperator + "socket" + path::path_seperator + "python_path", pythonBinary);
base.invalidate();
}
DemodConfig::DemodConfig(ConfigManager& cm, std::string path) : ConfigBase(cm, std::move(path)) {};
void DemodConfig::load() {
retuneDelay = base.pTree().get(basePath + path::path_seperator + "demod" + path::path_seperator + "retune_delay", static_cast<long int>(TUNER_RETUNE_TIME));
@ -194,6 +201,8 @@ void DemodConfig::save() {
base.pTree().put(basePath + path::path_seperator + "demod" + path::path_seperator + "squelch_mode", squelchType);
base.invalidate();
}
AudioServerConfig::AudioServerConfig(ConfigManager& cm, std::string path) : ConfigBase(cm, std::move(path)) {};
void AudioServerConfig::load() {
rtspPort = base.pTree().get(basePath + path::path_seperator + "audio_stream" + path::path_seperator + "rtsp_port", DEFAULT_RTSP_PORT);
@ -206,5 +215,49 @@ void AudioServerConfig::save() {
base.invalidate();
}
TunerList::TunerList(ConfigManager& cm, std::string path) : ConfigBase(cm, std::move(path)) {};
void TunerList::load() {
try {
BOOST_FOREACH(ptree::value_type& v, base.pTree().get_child(basePath + path::path_seperator + "tuners")){
ptree tunerPT = v.second;
TunerConfig tuner;
tuner.rank = tunerPT.get("rank", 0);
tuner.descriptor = tunerPT.get("descriptor", "null");
tuner.driver = tunerPT.get("driver", "null");
tuner.ppmCorrection = tunerPT.get("ppm_correction", 0);
tuner.sampleRate = tunerPT.get("sample_rate", 2048000);
RAW_LOG_F(2, "Tuner:");
RAW_LOG_F(2, "\tRank: %i", tuner.rank);
RAW_LOG_F(2, "\tDescriptor: %s", tuner.descriptor.c_str());
RAW_LOG_F(2, "\tDriver: %s", tuner.driver.c_str());
RAW_LOG_F(2, "\tPPM: %i", tuner.ppmCorrection);
RAW_LOG_F(2, "\tSample rate: %li", tuner.sampleRate);
tuners.insert(std::move(tuner));
}
} catch (std::exception& e) {
}
}
void TunerList::save() {
ptree tunerList, p;
base.pTree().erase(basePath + path::path_seperator + "tuners");
BOOST_FOREACH(const TunerConfig& c, tuners){
p.put("rank", c.rank);
p.put("descriptor", c.descriptor);
p.put("driver", c.driver);
p.put("ppm_correction", c.ppmCorrection);
p.put("sample_rate", c.sampleRate);
tunerList.push_back(std::make_pair("", p));
}
base.pTree().put_child(basePath + path::path_seperator + "tuners", tunerList);
}
}
}

View File

@ -9,6 +9,7 @@
#include <string>
#include <vector>
#include <set>
#include <boost/property_tree/ptree.hpp>
#include "constants.h"
@ -52,7 +53,7 @@ protected:
struct GeneralConfig : public ConfigBase {
public:
GeneralConfig(ConfigManager& cm, std::string path) : ConfigBase(cm, std::move(path)) {};
GeneralConfig(ConfigManager& cm, std::string path);
int logfileVerbosity = DEFAULT_LOGFILE_VERBOSITY;
@ -68,7 +69,7 @@ public:
struct SocketServerConfig : public ConfigBase {
public:
SocketServerConfig(ConfigManager& cm, std::string path) : ConfigBase(cm, std::move(path)) {};
SocketServerConfig(ConfigManager& cm, std::string path);
int tcpPort = DEFAULT_TCP_PORT;
int maxConnections = MAX_TCP_CONNECTIONS;
@ -90,7 +91,7 @@ public:
#define DEFAULT_SQUELCH_MODE (SQUELCH_DBM)
struct DemodConfig : public ConfigBase {
DemodConfig(ConfigManager& cm, std::string path) : ConfigBase(cm, std::move(path)) {};
DemodConfig(ConfigManager& cm, std::string path);
long int retuneDelay = TUNER_RETUNE_TIME;
long int demodDelay = DEMOD_BUFFER_TIME;
@ -101,24 +102,40 @@ struct DemodConfig : public ConfigBase {
};
#define DEFAULT_RANK 0
#define DEFAULT_DESC "NULL"
#define DEFAULT_DESC "null"
#define DEFAULT_DRIVER "null"
#define DEFAULT_PPM 0
#define DEFAULT_TUNER_SAMPLE_RATE 2048000
struct TunerConfig {
int rank = DEFAULT_RANK;
std::string description = DEFAULT_DESC;
std::string descriptor = DEFAULT_DESC;
std::string driver = DEFAULT_DRIVER;
int ppmCorrection = DEFAULT_PPM;
long int sampleRate = DEFAULT_TUNER_SAMPLE_RATE;
};
struct TunerList : public ConfigBase {
class TunerComparator : public std::less<TunerConfig> {
public:
constexpr bool operator()(const TunerConfig& left, const TunerConfig& right) const {
return left.rank < right.rank;
}
};
public:
TunerList(ConfigManager& cm, std::string path);
std::set<TunerConfig, TunerComparator> tuners;
virtual void save();
virtual void load();
};
#define DEFAULT_RTSP_PORT 8554
#define DEFAULT_RTSP_OVER_HTTP false
struct AudioServerConfig : public ConfigBase {
AudioServerConfig(ConfigManager& cm, std::string path) : ConfigBase(cm, std::move(path)) {};
AudioServerConfig(ConfigManager& cm, std::string path);
int rtspPort = DEFAULT_RTSP_PORT;
bool httpTunneling = DEFAULT_RTSP_OVER_HTTP;
@ -175,6 +192,7 @@ public:
SocketServerConfig& getSocketConfig() { return _socketConfig; };
DemodConfig& getDemodConfig() { return _demodConfig; };
AudioServerConfig& getAudioServerConfig() { return _rtspConfig; };
TunerList& getTunerList() { return _tunerList; };
std::string getLogDirectory();
std::string getDatedLogPath();
@ -191,6 +209,7 @@ private:
SocketServerConfig _socketConfig;
DemodConfig _demodConfig;
AudioServerConfig _rtspConfig;
TunerList _tunerList;
Configuration();

View File

@ -1,11 +1,13 @@
#include <functional>
#include "PiScan.h"
#include "TunerManager.h"
#include "CubicSDR.h"
#include "loguru.hpp"
#define AUDIO_DRIVER "audio"
using TunerList = piscan::config::TunerList;
namespace piscan{
namespace sigproc {
@ -56,7 +58,7 @@ bool TunerManager::selectFirstAvailableDevice() {
SDRDeviceInfo* device = (*(_devs.begin())).second;
_selectedTuner.device = device;
_selectedTuner.config.driver = device->getDriver();
_selectedTuner.config.description = device->getName();
_selectedTuner.config.descriptor = device->getName();
return true;
}
@ -94,27 +96,62 @@ long TunerManager::nearestSampleRate(long desired, std::vector<long>& supportedR
* @return False if a tuner could not be selected
*/
bool TunerManager::autoSelectTuner() {
TunerList& tunerList = piscan::app::system::getConfig().getTunerList();
if(_devs.empty()) {
LOG_F(WARNING, "No SDR devices were found");
return false;
}
if (_savedTuners.empty()) {
if (tunerList.tuners.empty()) {
// TODO temporary
LOG_F(INFO, "No saved tuners found in config, defaulting to first available");
selectFirstAvailableDevice();
LOG_F(INFO, "New tuner will be saved to config");
_savedTuners.push(_selectedTuner.config);
_selectedTuner.config.rank = tunerList.tuners.size();
tunerList.tuners.insert(_selectedTuner.config);
}
else {
bool foundTuner = false;
LOG_F(1, "Searching for known tuners...");
for (piscan::config::TunerConfig t : tunerList.tuners) {
auto dev = _devs.find(t.descriptor);
if (dev != _devs.end()) {
if (!(*dev).second->isAvailable()) {
LOG_F(WARNING, "Found tuner %s but it is unavailable", t.descriptor.c_str());
continue;
}
LOG_F(1, "Found tuner %s with rank %i", t.descriptor.c_str(), t.rank);
_selectedTuner.config = t;
_selectedTuner.device = (*dev).second;
foundTuner = true;
break;
}
}
// TODO temporary
if (!foundTuner) {
LOG_F(INFO, "No saved tuners were detected, defaulting to first available");
selectFirstAvailableDevice();
LOG_F(INFO, "New tuner will be saved to config");
_selectedTuner.config.rank = tunerList.tuners.size();
tunerList.tuners.insert(_selectedTuner.config);
}
}
LOG_F(INFO, "Auto selecting sample rate");
std::vector<long> srates(std::move(_selectedTuner.device->getSampleRates(SOAPY_SDR_RX, 0)));
RAW_LOG_F(1, "Supported sample rates for tuner:");
RAW_LOG_F(2, "Supported sample rates for tuner:");
for (long rate : srates)
RAW_LOG_F(1, "\t%li", rate);
RAW_LOG_F(2, "\t%li", rate);
_selectedTuner.config.sampleRate = nearestSampleRate(DEFAULT_TUNER_SAMPLE_RATE, srates); // TODO hardcoded sample rate temporary
_selectedTuner.config.sampleRate = nearestSampleRate(_selectedTuner.config.sampleRate, srates); // TODO hardcoded sample rate temporary
LOG_F(INFO, "Auto selected: %s", _selectedTuner.device->getName().c_str());

View File

@ -3,7 +3,6 @@
#include <vector>
#include <memory>
#include <unordered_map>
#include <queue>
#include "Configuration.h"
@ -12,13 +11,6 @@ class SDRDeviceInfo;
namespace piscan {
namespace sigproc {
class TunerComparator : public std::less<piscan::config::TunerConfig> {
public:
constexpr bool operator()(piscan::config::TunerConfig& left, piscan::config::TunerConfig& right) const {
return left.rank < right.rank;
}
};
struct ConfiguredTuner {
piscan::config::TunerConfig config; // TODO may be changed to ref or shared_ptr
SDRDeviceInfo* device;
@ -43,7 +35,6 @@ namespace sigproc {
private:
std::shared_ptr<CubicSDR> _cubic;
std::unordered_map<std::string, SDRDeviceInfo*> _devs;
std::priority_queue<piscan::config::TunerConfig, std::vector<piscan::config::TunerConfig>, TunerComparator> _savedTuners;
ConfiguredTuner _selectedTuner;
};
}