SDR++ server beta :)

This commit is contained in:
AlexandreRouma
2022-01-21 20:22:13 +01:00
parent 1185e4e114
commit 74b9d13360
37 changed files with 2731 additions and 498 deletions

View File

@ -7,9 +7,9 @@
#include <gui/style.h>
#include <config.h>
#include <options.h>
#include <gui/smgui.h>
#include <airspy.h>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
SDRPP_MOD_INFO{
@ -313,12 +313,12 @@ private:
static void menuHandler(void* ctx) {
AirspySourceModule* _this = (AirspySourceModule*)ctx;
float menuWidth = ImGui::GetContentRegionAvailWidth();
if (_this->running) { style::beginDisabled(); }
if (_this->running) { SmGui::BeginDisabled(); }
ImGui::SetNextItemWidth(menuWidth);
if (ImGui::Combo(CONCAT("##_airspy_dev_sel_", _this->name), &_this->devId, _this->devListTxt.c_str())) {
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Combo(CONCAT("##_airspy_dev_sel_", _this->name), &_this->devId, _this->devListTxt.c_str())) {
_this->selectBySerial(_this->devList[_this->devId]);
core::setInputSampleRate(_this->sampleRate);
if (_this->selectedSerStr != "") {
@ -328,7 +328,7 @@ private:
}
}
if (ImGui::Combo(CONCAT("##_airspy_sr_sel_", _this->name), &_this->srId, _this->sampleRateListTxt.c_str())) {
if (SmGui::Combo(CONCAT("##_airspy_sr_sel_", _this->name), &_this->srId, _this->sampleRateListTxt.c_str())) {
_this->sampleRate = _this->sampleRateList[_this->srId];
core::setInputSampleRate(_this->sampleRate);
if (_this->selectedSerStr != "") {
@ -338,9 +338,10 @@ private:
}
}
ImGui::SameLine();
float refreshBtnWdith = menuWidth - ImGui::GetCursorPosX();
if (ImGui::Button(CONCAT("Refresh##_airspy_refr_", _this->name), ImVec2(refreshBtnWdith, 0))) {
SmGui::SameLine();
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Button(CONCAT("Refresh##_airspy_refr_", _this->name))) {
_this->refresh();
config.acquire();
std::string devSerial = config.conf["device"];
@ -349,11 +350,12 @@ private:
core::setInputSampleRate(_this->sampleRate);
}
if (_this->running) { style::endDisabled(); }
if (_this->running) { SmGui::EndDisabled(); }
ImGui::BeginGroup();
ImGui::Columns(3, CONCAT("AirspyGainModeColumns##_", _this->name), false);
if (ImGui::RadioButton(CONCAT("Sensitive##_airspy_gm_", _this->name), _this->gainMode == 0)) {
SmGui::BeginGroup();
SmGui::Columns(3, CONCAT("AirspyGainModeColumns##_", _this->name), false);
SmGui::ForceSync();
if (SmGui::RadioButton(CONCAT("Sensitive##_airspy_gm_", _this->name), _this->gainMode == 0)) {
_this->gainMode = 0;
if (_this->running) {
airspy_set_lna_agc(_this->openDev, 0);
@ -366,8 +368,9 @@ private:
config.release(true);
}
}
ImGui::NextColumn();
if (ImGui::RadioButton(CONCAT("Linear##_airspy_gm_", _this->name), _this->gainMode == 1)) {
SmGui::NextColumn();
SmGui::ForceSync();
if (SmGui::RadioButton(CONCAT("Linear##_airspy_gm_", _this->name), _this->gainMode == 1)) {
_this->gainMode = 1;
if (_this->running) {
airspy_set_lna_agc(_this->openDev, 0);
@ -380,8 +383,9 @@ private:
config.release(true);
}
}
ImGui::NextColumn();
if (ImGui::RadioButton(CONCAT("Free##_airspy_gm_", _this->name), _this->gainMode == 2)) {
SmGui::NextColumn();
SmGui::ForceSync();
if (SmGui::RadioButton(CONCAT("Free##_airspy_gm_", _this->name), _this->gainMode == 2)) {
_this->gainMode = 2;
if (_this->running) {
if (_this->lnaAgc) {
@ -406,15 +410,15 @@ private:
config.release(true);
}
}
ImGui::Columns(1, CONCAT("EndAirspyGainModeColumns##_", _this->name), false);
ImGui::EndGroup();
SmGui::Columns(1, CONCAT("EndAirspyGainModeColumns##_", _this->name), false);
SmGui::EndGroup();
// Gain menus
if (_this->gainMode == 0) {
ImGui::LeftLabel("Gain");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::SliderInt(CONCAT("##_airspy_sens_gain_", _this->name), &_this->sensitiveGain, 0, 21)) {
SmGui::LeftLabel("Gain");
SmGui::FillWidth();
if (SmGui::SliderInt(CONCAT("##_airspy_sens_gain_", _this->name), &_this->sensitiveGain, 0, 21)) {
if (_this->running) {
airspy_set_sensitivity_gain(_this->openDev, _this->sensitiveGain);
}
@ -426,9 +430,9 @@ private:
}
}
else if (_this->gainMode == 1) {
ImGui::LeftLabel("Gain");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::SliderInt(CONCAT("##_airspy_lin_gain_", _this->name), &_this->linearGain, 0, 21)) {
SmGui::LeftLabel("Gain");
SmGui::FillWidth();
if (SmGui::SliderInt(CONCAT("##_airspy_lin_gain_", _this->name), &_this->linearGain, 0, 21)) {
if (_this->running) {
airspy_set_linearity_gain(_this->openDev, _this->linearGain);
}
@ -440,14 +444,11 @@ private:
}
}
else if (_this->gainMode == 2) {
// Calculate position of sliders
float pos = ImGui::CalcTextSize("Mixer Gain").x + 10;
if (_this->lnaAgc) { style::beginDisabled(); }
ImGui::LeftLabel("LNA Gain");
ImGui::SetCursorPosX(pos);
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::SliderInt(CONCAT("##_airspy_lna_gain_", _this->name), &_this->lnaGain, 0, 15)) {
// TODO: Switch to a table for alignement
if (_this->lnaAgc) { SmGui::BeginDisabled(); }
SmGui::LeftLabel("LNA Gain");
SmGui::FillWidth();
if (SmGui::SliderInt(CONCAT("##_airspy_lna_gain_", _this->name), &_this->lnaGain, 0, 15)) {
if (_this->running) {
airspy_set_lna_gain(_this->openDev, _this->lnaGain);
}
@ -457,13 +458,12 @@ private:
config.release(true);
}
}
if (_this->lnaAgc) { style::endDisabled(); }
if (_this->lnaAgc) { SmGui::EndDisabled(); }
if (_this->mixerAgc) { style::beginDisabled(); }
ImGui::LeftLabel("Mixer Gain");
ImGui::SetCursorPosX(pos);
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::SliderInt(CONCAT("##_airspy_mix_gain_", _this->name), &_this->mixerGain, 0, 15)) {
if (_this->mixerAgc) { SmGui::BeginDisabled(); }
SmGui::LeftLabel("Mixer Gain");
SmGui::FillWidth();
if (SmGui::SliderInt(CONCAT("##_airspy_mix_gain_", _this->name), &_this->mixerGain, 0, 15)) {
if (_this->running) {
airspy_set_mixer_gain(_this->openDev, _this->mixerGain);
}
@ -473,12 +473,11 @@ private:
config.release(true);
}
}
if (_this->mixerAgc) { style::endDisabled(); }
if (_this->mixerAgc) { SmGui::EndDisabled(); }
ImGui::LeftLabel("VGA Gain");
ImGui::SetCursorPosX(pos);
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::SliderInt(CONCAT("##_airspy_vga_gain_", _this->name), &_this->vgaGain, 0, 15)) {
SmGui::LeftLabel("VGA Gain");
SmGui::FillWidth();
if (SmGui::SliderInt(CONCAT("##_airspy_vga_gain_", _this->name), &_this->vgaGain, 0, 15)) {
if (_this->running) {
airspy_set_vga_gain(_this->openDev, _this->vgaGain);
}
@ -490,7 +489,8 @@ private:
}
// AGC Control
if (ImGui::Checkbox(CONCAT("LNA AGC##_airspy_", _this->name), &_this->lnaAgc)) {
SmGui::ForceSync();
if (SmGui::Checkbox(CONCAT("LNA AGC##_airspy_", _this->name), &_this->lnaAgc)) {
if (_this->running) {
if (_this->lnaAgc) {
airspy_set_lna_agc(_this->openDev, 1);
@ -506,7 +506,8 @@ private:
config.release(true);
}
}
if (ImGui::Checkbox(CONCAT("Mixer AGC##_airspy_", _this->name), &_this->mixerAgc)) {
SmGui::ForceSync();
if (SmGui::Checkbox(CONCAT("Mixer AGC##_airspy_", _this->name), &_this->mixerAgc)) {
if (_this->running) {
if (_this->mixerAgc) {
airspy_set_mixer_agc(_this->openDev, 1);
@ -525,8 +526,7 @@ private:
}
// Bias T
if (ImGui::Checkbox(CONCAT("Bias T##_airspy_", _this->name), &_this->biasT)) {
if (SmGui::Checkbox(CONCAT("Bias T##_airspy_", _this->name), &_this->biasT)) {
if (_this->running) {
airspy_set_rf_bias(_this->openDev, _this->biasT);
}

View File

@ -1,4 +1,3 @@
#include <imgui.h>
#include <spdlog/spdlog.h>
#include <module.h>
#include <gui/gui.h>
@ -7,6 +6,7 @@
#include <gui/style.h>
#include <config.h>
#include <options.h>
#include <gui/smgui.h>
#include <airspyhf.h>
#include <gui/widgets/stepped_slider.h>
@ -265,12 +265,12 @@ private:
static void menuHandler(void* ctx) {
AirspyHFSourceModule* _this = (AirspyHFSourceModule*)ctx;
float menuWidth = ImGui::GetContentRegionAvailWidth();
if (_this->running) { style::beginDisabled(); }
if (_this->running) { SmGui::BeginDisabled(); }
ImGui::SetNextItemWidth(menuWidth);
if (ImGui::Combo(CONCAT("##_airspyhf_dev_sel_", _this->name), &_this->devId, _this->devListTxt.c_str())) {
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Combo(CONCAT("##_airspyhf_dev_sel_", _this->name), &_this->devId, _this->devListTxt.c_str())) {
_this->selectBySerial(_this->devList[_this->devId]);
core::setInputSampleRate(_this->sampleRate);
if (_this->selectedSerStr != "") {
@ -280,7 +280,7 @@ private:
}
}
if (ImGui::Combo(CONCAT("##_airspyhf_sr_sel_", _this->name), &_this->srId, _this->sampleRateListTxt.c_str())) {
if (SmGui::Combo(CONCAT("##_airspyhf_sr_sel_", _this->name), &_this->srId, _this->sampleRateListTxt.c_str())) {
_this->sampleRate = _this->sampleRateList[_this->srId];
core::setInputSampleRate(_this->sampleRate);
if (_this->selectedSerStr != "") {
@ -290,9 +290,10 @@ private:
}
}
ImGui::SameLine();
float refreshBtnWdith = menuWidth - ImGui::GetCursorPosX();
if (ImGui::Button(CONCAT("Refresh##_airspyhf_refr_", _this->name), ImVec2(refreshBtnWdith, 0))) {
SmGui::SameLine();
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Button(CONCAT("Refresh##_airspyhf_refr_", _this->name))) {
_this->refresh();
config.acquire();
std::string devSerial = config.conf["device"];
@ -301,11 +302,11 @@ private:
core::setInputSampleRate(_this->sampleRate);
}
if (_this->running) { style::endDisabled(); }
if (_this->running) { SmGui::EndDisabled(); }
ImGui::LeftLabel("AGC Mode");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo(CONCAT("##_airspyhf_agc_", _this->name), &_this->agcMode, AGG_MODES_STR)) {
SmGui::LeftLabel("AGC Mode");
SmGui::FillWidth();
if (SmGui::Combo(CONCAT("##_airspyhf_agc_", _this->name), &_this->agcMode, AGG_MODES_STR)) {
if (_this->running) {
airspyhf_set_hf_agc(_this->openDev, (_this->agcMode != 0));
if (_this->agcMode > 0) {
@ -319,9 +320,9 @@ private:
}
}
ImGui::LeftLabel("Attenuation");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::SliderFloatWithSteps(CONCAT("##_airspyhf_attn_", _this->name), &_this->atten, 0, 48, 6, "%.0f dB")) {
SmGui::LeftLabel("Attenuation");
SmGui::FillWidth();
if (SmGui::SliderFloatWithSteps(CONCAT("##_airspyhf_attn_", _this->name), &_this->atten, 0, 48, 6, SmGui::FMT_STR_FLOAT_DB_NO_DECIMAL)) {
if (_this->running) {
airspyhf_set_hf_att(_this->openDev, _this->atten / 6.0f);
}
@ -332,7 +333,7 @@ private:
}
}
if (ImGui::Checkbox(CONCAT("HF LNA##_airspyhf_lna_", _this->name), &_this->hfLNA)) {
if (SmGui::Checkbox(CONCAT("HF LNA##_airspyhf_lna_", _this->name), &_this->hfLNA)) {
if (_this->running) {
airspyhf_set_hf_lna(_this->openDev, _this->hfLNA);
}

View File

@ -10,6 +10,7 @@
#include <gui/widgets/stepped_slider.h>
#include <libbladeRF.h>
#include <dsp/processing.h>
#include <gui/smgui.h>
#include <algorithm>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
@ -426,12 +427,12 @@ private:
static void menuHandler(void* ctx) {
BladeRFSourceModule* _this = (BladeRFSourceModule*)ctx;
float menuWidth = ImGui::GetContentRegionAvailWidth();
if (_this->running) { style::beginDisabled(); }
if (_this->running) { SmGui::BeginDisabled(); }
ImGui::SetNextItemWidth(menuWidth);
if (ImGui::Combo(CONCAT("##_balderf_dev_sel_", _this->name), &_this->devId, _this->devListTxt.c_str())) {
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Combo(CONCAT("##_balderf_dev_sel_", _this->name), &_this->devId, _this->devListTxt.c_str())) {
bladerf_devinfo info = _this->devInfoList[_this->devId];
_this->selectByInfo(&info);
core::setInputSampleRate(_this->sampleRate);
@ -440,7 +441,7 @@ private:
config.release(true);
}
if (ImGui::Combo(CONCAT("##_balderf_sr_sel_", _this->name), &_this->srId, _this->sampleRatesTxt.c_str())) {
if (SmGui::Combo(CONCAT("##_balderf_sr_sel_", _this->name), &_this->srId, _this->sampleRatesTxt.c_str())) {
_this->sampleRate = _this->sampleRates[_this->srId];
core::setInputSampleRate(_this->sampleRate);
if (_this->selectedSerial != "") {
@ -451,9 +452,10 @@ private:
}
// Refresh button
ImGui::SameLine();
float refreshBtnWdith = menuWidth - ImGui::GetCursorPosX();
if (ImGui::Button(CONCAT("Refresh##_balderf_refr_", _this->name), ImVec2(refreshBtnWdith, 0))) {
SmGui::SameLine();
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Button(CONCAT("Refresh##_balderf_refr_", _this->name))) {
_this->refresh();
_this->selectBySerial(_this->selectedSerial, false);
core::setInputSampleRate(_this->sampleRate);
@ -461,9 +463,9 @@ private:
// Channel selection (only show if more than one channel)
if (_this->channelCount > 1) {
ImGui::LeftLabel("RX Channel");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
ImGui::Combo(CONCAT("##_balderf_ch_sel_", _this->name), &_this->chanId, _this->channelNamesTxt.c_str());
SmGui::LeftLabel("RX Channel");
SmGui::FillWidth();
SmGui::Combo(CONCAT("##_balderf_ch_sel_", _this->name), &_this->chanId, _this->channelNamesTxt.c_str());
if (_this->selectedSerial != "") {
config.acquire();
config.conf["devices"][_this->selectedSerial]["channelId"] = _this->chanId;
@ -471,11 +473,11 @@ private:
}
}
if (_this->running) { style::endDisabled(); }
if (_this->running) { SmGui::EndDisabled(); }
ImGui::LeftLabel("Bandwidth");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo(CONCAT("##_balderf_bw_sel_", _this->name), &_this->bwId, _this->bandwidthsTxt.c_str())) {
SmGui::LeftLabel("Bandwidth");
SmGui::FillWidth();
if (SmGui::Combo(CONCAT("##_balderf_bw_sel_", _this->name), &_this->bwId, _this->bandwidthsTxt.c_str())) {
if (_this->running) {
bladerf_set_bandwidth(_this->openDev, BLADERF_CHANNEL_RX(_this->chanId), (_this->bwId == _this->bandwidths.size()) ? std::clamp<uint64_t>(_this->sampleRate, _this->bwRange->min, _this->bwRange->max) : _this->bandwidths[_this->bwId], NULL);
}
@ -487,9 +489,10 @@ private:
}
// General config BS
ImGui::LeftLabel("Gain control mode");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo(CONCAT("##_balderf_gm_sel_", _this->name), &_this->gainMode, _this->gainModesTxt.c_str()) && _this->selectedSerial != "") {
SmGui::LeftLabel("Gain control mode");
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Combo(CONCAT("##_balderf_gm_sel_", _this->name), &_this->gainMode, _this->gainModesTxt.c_str()) && _this->selectedSerial != "") {
if (_this->running) {
bladerf_set_gain_mode(_this->openDev, BLADERF_CHANNEL_RX(_this->chanId), _this->gainModes[_this->gainMode].mode);
}
@ -505,11 +508,11 @@ private:
}
if (_this->selectedSerial != "") {
if (_this->gainModes[_this->gainMode].mode != BLADERF_GAIN_MANUAL) { style::beginDisabled(); }
if (_this->gainModes[_this->gainMode].mode != BLADERF_GAIN_MANUAL) { SmGui::BeginDisabled(); }
}
ImGui::LeftLabel("Gain");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::SliderInt("##_balderf_oag_sel_", &_this->overallGain, (_this->gainRange != NULL) ? _this->gainRange->min : 0, (_this->gainRange != NULL) ? _this->gainRange->max : 60)) {
SmGui::LeftLabel("Gain");
SmGui::FillWidth();
if (SmGui::SliderInt("##_balderf_oag_sel_", &_this->overallGain, (_this->gainRange != NULL) ? _this->gainRange->min : 0, (_this->gainRange != NULL) ? _this->gainRange->max : 60)) {
if (_this->running) {
spdlog::info("Setting gain to {0}", _this->overallGain);
bladerf_set_gain(_this->openDev, BLADERF_CHANNEL_RX(_this->chanId), _this->overallGain);
@ -521,11 +524,11 @@ private:
}
}
if (_this->selectedSerial != "") {
if (_this->gainModes[_this->gainMode].mode != BLADERF_GAIN_MANUAL) { style::endDisabled(); }
if (_this->gainModes[_this->gainMode].mode != BLADERF_GAIN_MANUAL) { SmGui::EndDisabled(); }
}
if (_this->selectedBladeType == BLADERF_TYPE_V2) {
if (ImGui::Checkbox("Bias-T##_balderf_biast_", &_this->biasT)) {
if (SmGui::Checkbox("Bias-T##_balderf_biast_", &_this->biasT)) {
if (_this->running) {
bladerf_set_bias_tee(_this->openDev, BLADERF_CHANNEL_RX(_this->chanId), _this->biasT);
}

View File

@ -28,6 +28,8 @@ public:
FileSourceModule(std::string name) : fileSelect("", { "Wav IQ Files (*.wav)", "*.wav", "All Files", "*" }) {
this->name = name;
if (options::opts.serverMode) { return; }
config.acquire();
fileSelect.setPath(config.conf["path"], true);
config.release();

View File

@ -1,4 +1,3 @@
#include <imgui.h>
#include <spdlog/spdlog.h>
#include <module.h>
#include <gui/gui.h>
@ -9,6 +8,7 @@
#include <libhackrf/hackrf.h>
#include <gui/widgets/stepped_slider.h>
#include <options.h>
#include <gui/smgui.h>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
@ -275,19 +275,18 @@ private:
static void menuHandler(void* ctx) {
HackRFSourceModule* _this = (HackRFSourceModule*)ctx;
float menuWidth = ImGui::GetContentRegionAvailWidth();
if (_this->running) { style::beginDisabled(); }
ImGui::SetNextItemWidth(menuWidth);
if (ImGui::Combo(CONCAT("##_hackrf_dev_sel_", _this->name), &_this->devId, _this->devListTxt.c_str())) {
_this->selectedSerial = _this->devList[_this->devId];
if (_this->running) { SmGui::BeginDisabled(); }
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Combo(CONCAT("##_hackrf_dev_sel_", _this->name), &_this->devId, _this->devListTxt.c_str())) {
_this->selectBySerial(_this->devList[_this->devId]);
config.acquire();
config.conf["device"] = _this->selectedSerial;
config.release(true);
}
if (ImGui::Combo(CONCAT("##_hackrf_sr_sel_", _this->name), &_this->srId, sampleRatesTxt)) {
if (SmGui::Combo(CONCAT("##_hackrf_sr_sel_", _this->name), &_this->srId, sampleRatesTxt)) {
_this->sampleRate = sampleRates[_this->srId];
core::setInputSampleRate(_this->sampleRate);
config.acquire();
@ -295,19 +294,20 @@ private:
config.release(true);
}
ImGui::SameLine();
float refreshBtnWdith = menuWidth - ImGui::GetCursorPosX();
if (ImGui::Button(CONCAT("Refresh##_hackrf_refr_", _this->name), ImVec2(refreshBtnWdith, 0))) {
SmGui::SameLine();
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Button(CONCAT("Refresh##_hackrf_refr_", _this->name))) {
_this->refresh();
_this->selectBySerial(_this->selectedSerial);
core::setInputSampleRate(_this->sampleRate);
}
if (_this->running) { style::endDisabled(); }
if (_this->running) { SmGui::EndDisabled(); }
ImGui::LeftLabel("Bandwidth");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo(CONCAT("##_hackrf_bw_sel_", _this->name), &_this->bwId, bandwidthsTxt)) {
SmGui::LeftLabel("Bandwidth");
SmGui::FillWidth();
if (SmGui::Combo(CONCAT("##_hackrf_bw_sel_", _this->name), &_this->bwId, bandwidthsTxt)) {
if (_this->running) {
hackrf_set_baseband_filter_bandwidth(_this->openDev, _this->bandwidthIdToBw(_this->bwId));
}
@ -316,9 +316,9 @@ private:
config.release(true);
}
ImGui::LeftLabel("LNA Gain");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::SliderFloatWithSteps(CONCAT("##_hackrf_lna_", _this->name), &_this->lna, 0, 40, 8, "%.0fdB")) {
SmGui::LeftLabel("LNA Gain");
SmGui::FillWidth();
if (SmGui::SliderFloatWithSteps(CONCAT("##_hackrf_lna_", _this->name), &_this->lna, 0, 40, 8, SmGui::FMT_STR_FLOAT_DB_NO_DECIMAL)) {
if (_this->running) {
hackrf_set_lna_gain(_this->openDev, _this->lna);
}
@ -327,9 +327,9 @@ private:
config.release(true);
}
ImGui::LeftLabel("VGA Gain");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::SliderFloatWithSteps(CONCAT("##_hackrf_vga_", _this->name), &_this->vga, 0, 62, 2, "%.0fdB")) {
SmGui::LeftLabel("VGA Gain");
SmGui::FillWidth();
if (SmGui::SliderFloatWithSteps(CONCAT("##_hackrf_vga_", _this->name), &_this->vga, 0, 62, 2, SmGui::FMT_STR_FLOAT_DB_NO_DECIMAL)) {
if (_this->running) {
hackrf_set_vga_gain(_this->openDev, _this->vga);
}
@ -338,7 +338,7 @@ private:
config.release(true);
}
if (ImGui::Checkbox(CONCAT("Bias-T##_hackrf_bt_", _this->name), &_this->biasT)) {
if (SmGui::Checkbox(CONCAT("Bias-T##_hackrf_bt_", _this->name), &_this->biasT)) {
if (_this->running) {
hackrf_set_antenna_enable(_this->openDev, _this->biasT);
}
@ -347,7 +347,7 @@ private:
config.release(true);
}
if (ImGui::Checkbox(CONCAT("Amp Enabled##_hackrf_amp_", _this->name), &_this->amp)) {
if (SmGui::Checkbox(CONCAT("Amp Enabled##_hackrf_amp_", _this->name), &_this->amp)) {
if (_this->running) {
hackrf_set_amp_enable(_this->openDev, _this->amp);
}

View File

@ -1,4 +1,3 @@
#include <imgui.h>
#include <spdlog/spdlog.h>
#include <module.h>
#include <gui/gui.h>
@ -7,6 +6,7 @@
#include <gui/style.h>
#include <config.h>
#include <options.h>
#include <gui/smgui.h>
#include <lime/LimeSuite.h>
@ -382,12 +382,12 @@ private:
static void menuHandler(void* ctx) {
LimeSDRSourceModule* _this = (LimeSDRSourceModule*)ctx;
float menuWidth = ImGui::GetContentRegionAvailWidth();
if (_this->running) { style::beginDisabled(); }
if (_this->running) { SmGui::BeginDisabled(); }
ImGui::SetNextItemWidth(menuWidth);
if (ImGui::Combo("##limesdr_dev_sel", &_this->devId, _this->devListTxt.c_str())) {
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Combo("##limesdr_dev_sel", &_this->devId, _this->devListTxt.c_str())) {
_this->selectByInfoStr(_this->devList[_this->devId]);
core::setInputSampleRate(_this->sampleRate);
config.acquire();
@ -395,7 +395,7 @@ private:
config.release(true);
}
if (ImGui::Combo(CONCAT("##_limesdr_sr_sel_", _this->name), &_this->srId, _this->sampleRatesTxt.c_str())) {
if (SmGui::Combo(CONCAT("##_limesdr_sr_sel_", _this->name), &_this->srId, _this->sampleRatesTxt.c_str())) {
_this->sampleRate = _this->sampleRates[_this->srId];
core::setInputSampleRate(_this->sampleRate);
if (_this->selectedDevName != "") {
@ -406,29 +406,30 @@ private:
}
// Refresh button
ImGui::SameLine();
float refreshBtnWdith = menuWidth - ImGui::GetCursorPosX();
if (ImGui::Button(CONCAT("Refresh##_limesdr_refr_", _this->name), ImVec2(refreshBtnWdith, 0))) {
SmGui::SameLine();
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Button(CONCAT("Refresh##_limesdr_refr_", _this->name))) {
_this->refresh();
_this->selectByName(_this->selectedDevName);
core::setInputSampleRate(_this->sampleRate);
}
if (_this->channelCount > 1) {
ImGui::LeftLabel("RX Channel");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo("##limesdr_ch_sel", &_this->chanId, _this->channelNamesTxt.c_str()) && _this->selectedDevName != "") {
SmGui::LeftLabel("RX Channel");
SmGui::FillWidth();
if (SmGui::Combo("##limesdr_ch_sel", &_this->chanId, _this->channelNamesTxt.c_str()) && _this->selectedDevName != "") {
config.acquire();
config.conf["devices"][_this->selectedDevName]["channel"] = _this->chanId;
config.release(true);
}
}
if (_this->running) { style::endDisabled(); }
if (_this->running) { SmGui::EndDisabled(); }
ImGui::LeftLabel("Antenna");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo("##limesdr_ant_sel", &_this->antennaId, _this->antennaListTxt.c_str())) {
SmGui::LeftLabel("Antenna");
SmGui::FillWidth();
if (SmGui::Combo("##limesdr_ant_sel", &_this->antennaId, _this->antennaListTxt.c_str())) {
if (_this->running) {
LMS_SetAntenna(_this->openDev, false, _this->chanId, _this->antennaId);
}
@ -439,9 +440,9 @@ private:
}
}
ImGui::LeftLabel("Bandwidth");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo("##limesdr_bw_sel", &_this->bwId, _this->bandwidthsTxt.c_str())) {
SmGui::LeftLabel("Bandwidth");
SmGui::FillWidth();
if (SmGui::Combo("##limesdr_bw_sel", &_this->bwId, _this->bandwidthsTxt.c_str())) {
if (_this->running) {
LMS_SetLPFBW(_this->openDev, false, _this->chanId, (_this->bwId == _this->bandwidths.size()) ? _this->getBestBandwidth(_this->sampleRate) : _this->bandwidths[_this->bwId]);
}
@ -452,9 +453,9 @@ private:
}
}
ImGui::LeftLabel("Gain");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::SliderInt("##limesdr_gain_sel", &_this->gain, 0, 73, "%ddB")) {
SmGui::LeftLabel("Gain");
SmGui::FillWidth();
if (SmGui::SliderInt("##limesdr_gain_sel", &_this->gain, 0, 73, SmGui::FMT_STR_INT_DB)) {
if (_this->running) {
LMS_SetGaindB(_this->openDev, false, _this->chanId, _this->gain);
}

View File

@ -1,10 +1,10 @@
#include <imgui.h>
#include <spdlog/spdlog.h>
#include <module.h>
#include <gui/gui.h>
#include <signal_path/signal_path.h>
#include <core.h>
#include <gui/style.h>
#include <gui/smgui.h>
#include <iio.h>
#include <ad9361.h>
#include <options.h>
@ -185,32 +185,31 @@ private:
static void menuHandler(void* ctx) {
PlutoSDRSourceModule* _this = (PlutoSDRSourceModule*)ctx;
float menuWidth = ImGui::GetContentRegionAvailWidth();
if (_this->running) { style::beginDisabled(); }
ImGui::LeftLabel("IP");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::InputText(CONCAT("##_pluto_ip_", _this->name), &_this->ip[3], 16)) {
if (_this->running) { SmGui::BeginDisabled(); }
SmGui::LeftLabel("IP");
SmGui::FillWidth();
if (SmGui::InputText(CONCAT("##_pluto_ip_", _this->name), &_this->ip[3], 16)) {
config.acquire();
config.conf["IP"] = &_this->ip[3];
config.release(true);
}
ImGui::LeftLabel("Samplerate");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo(CONCAT("##_pluto_sr_", _this->name), &_this->srId, _this->sampleRatesTxt.c_str())) {
SmGui::LeftLabel("Samplerate");
SmGui::FillWidth();
if (SmGui::Combo(CONCAT("##_pluto_sr_", _this->name), &_this->srId, _this->sampleRatesTxt.c_str())) {
_this->sampleRate = _this->sampleRates[_this->srId];
core::setInputSampleRate(_this->sampleRate);
config.acquire();
config.conf["sampleRate"] = _this->sampleRate;
config.release(true);
}
if (_this->running) { style::endDisabled(); }
if (_this->running) { SmGui::EndDisabled(); }
ImGui::LeftLabel("Gain Mode");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo(CONCAT("##_gainmode_select_", _this->name), &_this->gainMode, gainModesTxt)) {
SmGui::LeftLabel("Gain Mode");
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Combo(CONCAT("##_gainmode_select_", _this->name), &_this->gainMode, gainModesTxt)) {
if (_this->running) {
iio_channel_attr_write(iio_device_find_channel(_this->phy, "voltage0", false), "gain_control_mode", gainModes[_this->gainMode]);
}
@ -219,10 +218,10 @@ private:
config.release(true);
}
ImGui::LeftLabel("PGA Gain");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (_this->gainMode) { style::beginDisabled(); }
if (ImGui::SliderFloat(CONCAT("##_gain_select_", _this->name), &_this->gain, 0, 76)) {
SmGui::LeftLabel("PGA Gain");
if (_this->gainMode) { SmGui::BeginDisabled(); }
SmGui::FillWidth();
if (SmGui::SliderFloat(CONCAT("##_gain_select_", _this->name), &_this->gain, 0, 76)) {
if (_this->running) {
iio_channel_attr_write_longlong(iio_device_find_channel(_this->phy, "voltage0", false), "hardwaregain", round(_this->gain));
}
@ -230,7 +229,7 @@ private:
config.conf["gain"] = _this->gain;
config.release(true);
}
if (_this->gainMode) { style::endDisabled(); }
if (_this->gainMode) { SmGui::EndDisabled(); }
}
static void worker(void* ctx) {

View File

@ -10,6 +10,7 @@
#include <options.h>
#include <gui/widgets/stepped_slider.h>
#include <utils/optionlist.h>
#include <gui/smgui.h>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
@ -23,9 +24,9 @@ SDRPP_MOD_INFO{
ConfigManager config;
class RFSpaceSource : public ModuleManager::Instance {
class RFSpaceSourceModule : public ModuleManager::Instance {
public:
RFSpaceSource(std::string name) {
RFSpaceSourceModule(std::string name) {
this->name = name;
handler.ctx = this;
@ -47,7 +48,7 @@ public:
sigpath::sourceManager.registerSource("RFspace", &handler);
}
~RFSpaceSource() {
~RFSpaceSourceModule() {
stop(this);
sigpath::sourceManager.unregisterSource("RFspace");
}
@ -82,72 +83,73 @@ private:
}
static void menuSelected(void* ctx) {
RFSpaceSource* _this = (RFSpaceSource*)ctx;
RFSpaceSourceModule* _this = (RFSpaceSourceModule*)ctx;
core::setInputSampleRate(_this->sampleRate);
gui::mainWindow.playButtonLocked = !(_this->client && _this->client->isOpen());
spdlog::info("RFSpaceSource '{0}': Menu Select!", _this->name);
spdlog::info("RFSpaceSourceModule '{0}': Menu Select!", _this->name);
}
static void menuDeselected(void* ctx) {
RFSpaceSource* _this = (RFSpaceSource*)ctx;
RFSpaceSourceModule* _this = (RFSpaceSourceModule*)ctx;
gui::mainWindow.playButtonLocked = false;
spdlog::info("RFSpaceSource '{0}': Menu Deselect!", _this->name);
spdlog::info("RFSpaceSourceModule '{0}': Menu Deselect!", _this->name);
}
static void start(void* ctx) {
RFSpaceSource* _this = (RFSpaceSource*)ctx;
RFSpaceSourceModule* _this = (RFSpaceSourceModule*)ctx;
if (_this->running) { return; }
// TODO: Set configuration here
if (_this->client) { _this->client->start(rfspace::RFSPACE_SAMP_FORMAT_COMPLEX, rfspace::RFSPACE_SAMP_FORMAT_16BIT); }
_this->running = true;
spdlog::info("RFSpaceSource '{0}': Start!", _this->name);
spdlog::info("RFSpaceSourceModule '{0}': Start!", _this->name);
}
static void stop(void* ctx) {
RFSpaceSource* _this = (RFSpaceSource*)ctx;
RFSpaceSourceModule* _this = (RFSpaceSourceModule*)ctx;
if (!_this->running) { return; }
if (_this->client) { _this->client->stop(); }
_this->running = false;
spdlog::info("RFSpaceSource '{0}': Stop!", _this->name);
spdlog::info("RFSpaceSourceModule '{0}': Stop!", _this->name);
}
static void tune(double freq, void* ctx) {
RFSpaceSource* _this = (RFSpaceSource*)ctx;
RFSpaceSourceModule* _this = (RFSpaceSourceModule*)ctx;
if (_this->running && _this->client) {
_this->client->setFrequency(freq);
}
_this->freq = freq;
spdlog::info("RFSpaceSource '{0}': Tune: {1}!", _this->name, freq);
spdlog::info("RFSpaceSourceModule '{0}': Tune: {1}!", _this->name, freq);
}
static void menuHandler(void* ctx) {
RFSpaceSource* _this = (RFSpaceSource*)ctx;
float menuWidth = ImGui::GetContentRegionAvailWidth();
RFSpaceSourceModule* _this = (RFSpaceSourceModule*)ctx;
bool connected = (_this->client && _this->client->isOpen());
gui::mainWindow.playButtonLocked = !connected;
if (connected) { style::beginDisabled(); }
if (ImGui::InputText(CONCAT("##_rfspace_srv_host_", _this->name), _this->hostname, 1023)) {
if (connected) { SmGui::BeginDisabled(); }
if (SmGui::InputText(CONCAT("##_rfspace_srv_host_", _this->name), _this->hostname, 1023)) {
config.acquire();
config.conf["hostname"] = _this->hostname;
config.release(true);
}
ImGui::SameLine();
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::InputInt(CONCAT("##_rfspace_srv_port_", _this->name), &_this->port, 0, 0)) {
SmGui::SameLine();
SmGui::FillWidth();
if (SmGui::InputInt(CONCAT("##_rfspace_srv_port_", _this->name), &_this->port, 0, 0)) {
config.acquire();
config.conf["port"] = _this->port;
config.release(true);
}
if (connected) { style::endDisabled(); }
if (connected) { SmGui::EndDisabled(); }
if (_this->running) { style::beginDisabled(); }
if (!connected && ImGui::Button("Connect##rfspace_source", ImVec2(menuWidth, 0))) {
if (_this->running) { SmGui::BeginDisabled(); }
SmGui::FillWidth();
SmGui::ForceSync();
if (!connected && SmGui::Button("Connect##rfspace_source")) {
try {
if (_this->client) { _this->client.reset(); }
_this->client = rfspace::connect(_this->hostname, _this->port, &_this->stream);
@ -157,18 +159,18 @@ private:
spdlog::error("Could not connect to SDR: {0}", e.what());
}
}
else if (connected && ImGui::Button("Disconnect##rfspace_source", ImVec2(menuWidth, 0))) {
else if (connected && SmGui::Button("Disconnect##rfspace_source")) {
_this->client->close();
}
if (_this->running) { style::endDisabled(); }
if (_this->running) { SmGui::EndDisabled(); }
if (connected) {
if (_this->running) { style::beginDisabled(); }
if (_this->running) { SmGui::BeginDisabled(); }
ImGui::LeftLabel("Samplerate");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo("##rfspace_source_samp_rate", &_this->srId, _this->sampleRates.txt)) {
SmGui::LeftLabel("Samplerate");
SmGui::FillWidth();
if (SmGui::Combo("##rfspace_source_samp_rate", &_this->srId, _this->sampleRates.txt)) {
_this->sampleRate = _this->sampleRates[_this->srId];
_this->client->setSampleRate(_this->sampleRate);
core::setInputSampleRate(_this->sampleRate);
@ -178,12 +180,12 @@ private:
config.release(true);
}
if (_this->running) { style::endDisabled(); }
if (_this->running) { SmGui::EndDisabled(); }
if (_this->client->deviceId == rfspace::RFSPACE_DEV_ID_CLOUD_IQ) {
ImGui::LeftLabel("Antenna Port");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo("##rfspace_source_rf_port", &_this->rfPortId, _this->rfPorts.txt)) {
SmGui::LeftLabel("Antenna Port");
SmGui::FillWidth();
if (SmGui::Combo("##rfspace_source_rf_port", &_this->rfPortId, _this->rfPorts.txt)) {
_this->client->setPort(_this->rfPorts[_this->rfPortId]);
config.acquire();
@ -192,9 +194,9 @@ private:
}
}
ImGui::LeftLabel("Gain");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::SliderFloatWithSteps("##rfspace_source_gain", &_this->gain, -30, 0, 10, "%.0f dB")) {
SmGui::LeftLabel("Gain");
SmGui::FillWidth();
if (SmGui::SliderFloatWithSteps("##rfspace_source_gain", &_this->gain, -30, 0, 10, SmGui::FMT_STR_FLOAT_DB_NO_DECIMAL)) {
_this->client->setGain(_this->gain);
config.acquire();
@ -202,14 +204,14 @@ private:
config.release(true);
}
ImGui::Text("Status:");
ImGui::SameLine();
ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "Connected (%s)", _this->deviceName.c_str());
SmGui::Text("Status:");
SmGui::SameLine();
SmGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), _this->connectedStr.c_str());
}
else {
ImGui::Text("Status:");
ImGui::SameLine();
ImGui::Text("Not connected");
SmGui::Text("Status:");
SmGui::SameLine();
SmGui::Text("Not connected");
}
}
@ -218,6 +220,8 @@ private:
char buf[4096];
sprintf(buf, "%s:%05d", hostname, port);
devConfName = buf;
sprintf(buf, "Connected (%s:%05d)", hostname, port);
connectedStr = buf;
// Get device name
if (deviceNames.find(client->deviceId) != deviceNames.end()) {
@ -301,6 +305,7 @@ private:
char hostname[1024];
int port = 50000;
std::string devConfName = "";
std::string connectedStr = "";
std::string deviceName = "Unknown";
std::map<rfspace::DeviceID, std::string> deviceNames = {
@ -321,7 +326,7 @@ MOD_EXPORT void _INIT_() {
def["hostname"] = "192.168.0.111";
def["port"] = 50000;
def["devices"] = json::object();
config.setPath(options::opts.root + "/rfspace_config.json");
config.setPath(options::opts.root + "/rfspace_source_config.json");
config.load(def);
config.enableAutoSave();
@ -336,11 +341,11 @@ MOD_EXPORT void _INIT_() {
}
MOD_EXPORT ModuleManager::Instance* _CREATE_INSTANCE_(std::string name) {
return new RFSpaceSource(name);
return new RFSpaceSourceModule(name);
}
MOD_EXPORT void _DELETE_INSTANCE_(ModuleManager::Instance* instance) {
delete (RFSpaceSource*)instance;
delete (RFSpaceSourceModule*)instance;
}
MOD_EXPORT void _END_() {

View File

@ -1,4 +1,3 @@
#include <imgui.h>
#include <spdlog/spdlog.h>
#include <module.h>
#include <gui/gui.h>
@ -7,6 +6,7 @@
#include <gui/style.h>
#include <config.h>
#include <options.h>
#include <gui/smgui.h>
#include <rtl-sdr.h>
@ -315,12 +315,11 @@ private:
static void menuHandler(void* ctx) {
RTLSDRSourceModule* _this = (RTLSDRSourceModule*)ctx;
float menuWidth = ImGui::GetContentRegionAvailWidth();
if (_this->running) { style::beginDisabled(); }
ImGui::SetNextItemWidth(menuWidth);
if (ImGui::Combo(CONCAT("##_rtlsdr_dev_sel_", _this->name), &_this->devId, _this->devListTxt.c_str())) {
if (_this->running) { SmGui::BeginDisabled(); }
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Combo(CONCAT("##_rtlsdr_dev_sel_", _this->name), &_this->devId, _this->devListTxt.c_str())) {
_this->selectById(_this->devId);
core::setInputSampleRate(_this->sampleRate);
if (_this->selectedDevName != "") {
@ -330,7 +329,7 @@ private:
}
}
if (ImGui::Combo(CONCAT("##_rtlsdr_sr_sel_", _this->name), &_this->srId, _this->sampleRateListTxt.c_str())) {
if (SmGui::Combo(CONCAT("##_rtlsdr_sr_sel_", _this->name), &_this->srId, _this->sampleRateListTxt.c_str())) {
_this->sampleRate = sampleRates[_this->srId];
core::setInputSampleRate(_this->sampleRate);
if (_this->selectedDevName != "") {
@ -340,20 +339,21 @@ private:
}
}
ImGui::SameLine();
float refreshBtnWdith = menuWidth - ImGui::GetCursorPosX();
if (ImGui::Button(CONCAT("Refresh##_rtlsdr_refr_", _this->name), ImVec2(refreshBtnWdith, 0))) {
SmGui::SameLine();
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Button(CONCAT("Refresh##_rtlsdr_refr_", _this->name)/*, ImVec2(refreshBtnWdith, 0)*/)) {
_this->refresh();
_this->selectByName(_this->selectedDevName);
core::setInputSampleRate(_this->sampleRate);
}
if (_this->running) { style::endDisabled(); }
if (_this->running) { SmGui::EndDisabled(); }
// Rest of rtlsdr config here
ImGui::LeftLabel("Direct Sampling");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo(CONCAT("##_rtlsdr_ds_", _this->name), &_this->directSamplingMode, directSamplingModesTxt)) {
SmGui::LeftLabel("Direct Sampling");
SmGui::FillWidth();
if (SmGui::Combo(CONCAT("##_rtlsdr_ds_", _this->name), &_this->directSamplingMode, directSamplingModesTxt)) {
if (_this->running) {
rtlsdr_set_direct_sampling(_this->openDev, _this->directSamplingMode);
@ -376,9 +376,9 @@ private:
}
}
ImGui::LeftLabel("PPM Correction");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::InputInt(CONCAT("##_rtlsdr_ppm_", _this->name), &_this->ppm, 1, 10)) {
SmGui::LeftLabel("PPM Correction");
SmGui::FillWidth();
if (SmGui::InputInt(CONCAT("##_rtlsdr_ppm_", _this->name), &_this->ppm, 1, 10)) {
_this->ppm = std::clamp<int>(_this->ppm, -1000000, 1000000);
if (_this->running) {
rtlsdr_set_freq_correction(_this->openDev, _this->ppm);
@ -390,22 +390,42 @@ private:
}
}
if (_this->tunerAgc || _this->gainList.size() == 0) { style::beginDisabled(); }
ImGui::SetNextItemWidth(menuWidth);
if (ImGui::SliderInt(CONCAT("##_rtlsdr_gain_", _this->name), &_this->gainId, 0, _this->gainList.size() - 1, _this->dbTxt)) {
_this->updateGainTxt();
if (_this->running) {
rtlsdr_set_tuner_gain(_this->openDev, _this->gainList[_this->gainId]);
}
if (_this->selectedDevName != "") {
config.acquire();
config.conf["devices"][_this->selectedDevName]["gain"] = _this->gainId;
config.release(true);
if (_this->tunerAgc || _this->gainList.size() == 0) { SmGui::BeginDisabled(); }
SmGui::FillWidth();
SmGui::ForceSync();
// TODO: FIND ANOTHER WAY
if (options::opts.serverMode) {
if (SmGui::SliderInt(CONCAT("##_rtlsdr_gain_", _this->name), &_this->gainId, 0, _this->gainList.size() - 1, SmGui::FMT_STR_NONE)) {
_this->updateGainTxt();
if (_this->running) {
rtlsdr_set_tuner_gain(_this->openDev, _this->gainList[_this->gainId]);
}
if (_this->selectedDevName != "") {
config.acquire();
config.conf["devices"][_this->selectedDevName]["gain"] = _this->gainId;
config.release(true);
}
}
}
else {
if (ImGui::SliderInt(CONCAT("##_rtlsdr_gain_", _this->name), &_this->gainId, 0, _this->gainList.size() - 1, _this->dbTxt)) {
_this->updateGainTxt();
if (_this->running) {
rtlsdr_set_tuner_gain(_this->openDev, _this->gainList[_this->gainId]);
}
if (_this->selectedDevName != "") {
config.acquire();
config.conf["devices"][_this->selectedDevName]["gain"] = _this->gainId;
config.release(true);
}
}
}
if (_this->tunerAgc || _this->gainList.size() == 0) { style::endDisabled(); }
if (ImGui::Checkbox(CONCAT("Bias T##_rtlsdr_rtl_biast_", _this->name), &_this->biasT)) {
if (_this->tunerAgc || _this->gainList.size() == 0) { SmGui::EndDisabled(); }
if (SmGui::Checkbox(CONCAT("Bias T##_rtlsdr_rtl_biast_", _this->name), &_this->biasT)) {
if (_this->running) {
rtlsdr_set_bias_tee(_this->openDev, _this->biasT);
}
@ -416,7 +436,7 @@ private:
}
}
if (ImGui::Checkbox(CONCAT("Offset Tuning##_rtlsdr_rtl_ofs_", _this->name), &_this->offsetTuning)) {
if (SmGui::Checkbox(CONCAT("Offset Tuning##_rtlsdr_rtl_ofs_", _this->name), &_this->offsetTuning)) {
if (_this->running) {
rtlsdr_set_offset_tuning(_this->openDev, _this->offsetTuning);
}
@ -427,7 +447,7 @@ private:
}
}
if (ImGui::Checkbox(CONCAT("RTL AGC##_rtlsdr_rtl_agc_", _this->name), &_this->rtlAgc)) {
if (SmGui::Checkbox(CONCAT("RTL AGC##_rtlsdr_rtl_agc_", _this->name), &_this->rtlAgc)) {
if (_this->running) {
rtlsdr_set_agc_mode(_this->openDev, _this->rtlAgc);
}
@ -438,7 +458,8 @@ private:
}
}
if (ImGui::Checkbox(CONCAT("Tuner AGC##_rtlsdr_tuner_agc_", _this->name), &_this->tunerAgc)) {
SmGui::ForceSync();
if (SmGui::Checkbox(CONCAT("Tuner AGC##_rtlsdr_tuner_agc_", _this->name), &_this->tunerAgc)) {
if (_this->running) {
if (_this->tunerAgc) {
rtlsdr_set_tuner_gain_mode(_this->openDev, 0);

View File

@ -6,6 +6,7 @@
#include <signal_path/signal_path.h>
#include <core.h>
#include <options.h>
#include <gui/smgui.h>
#include <gui/style.h>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
@ -188,27 +189,24 @@ private:
static void menuHandler(void* ctx) {
RTLTCPSourceModule* _this = (RTLTCPSourceModule*)ctx;
float menuWidth = ImGui::GetContentRegionAvailWidth();
float portWidth = ImGui::CalcTextSize("00000").x + 20;
if (_this->running) { style::beginDisabled(); }
if (_this->running) { SmGui::BeginDisabled(); }
ImGui::SetNextItemWidth(menuWidth - portWidth);
if (ImGui::InputText(CONCAT("##_ip_select_", _this->name), _this->ip, 1024)) {
if (SmGui::InputText(CONCAT("##_ip_select_", _this->name), _this->ip, 1024)) {
config.acquire();
config.conf["host"] = std::string(_this->ip);
config.release(true);
}
ImGui::SameLine();
ImGui::SetNextItemWidth(portWidth);
if (ImGui::InputInt(CONCAT("##_port_select_", _this->name), &_this->port, 0)) {
SmGui::SameLine();
SmGui::FillWidth();
if (SmGui::InputInt(CONCAT("##_port_select_", _this->name), &_this->port, 0)) {
config.acquire();
config.conf["port"] = _this->port;
config.release(true);
}
ImGui::SetNextItemWidth(menuWidth);
if (ImGui::Combo(CONCAT("##_rtltcp_sr_", _this->name), &_this->srId, _this->srTxt.c_str())) {
SmGui::FillWidth();
if (SmGui::Combo(CONCAT("##_rtltcp_sr_", _this->name), &_this->srId, _this->srTxt.c_str())) {
_this->sampleRate = sampleRates[_this->srId];
core::setInputSampleRate(_this->sampleRate);
config.acquire();
@ -216,11 +214,11 @@ private:
config.release(true);
}
if (_this->running) { style::endDisabled(); }
if (_this->running) { SmGui::EndDisabled(); }
ImGui::LeftLabel("Direct Sampling");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo(CONCAT("##_rtltcp_ds_", _this->name), &_this->directSamplingMode, "Disabled\0I branch\0Q branch\0")) {
SmGui::LeftLabel("Direct Sampling");
SmGui::FillWidth();
if (SmGui::Combo(CONCAT("##_rtltcp_ds_", _this->name), &_this->directSamplingMode, "Disabled\0I branch\0Q branch\0")) {
if (_this->running) {
_this->client.setDirectSampling(_this->directSamplingMode);
_this->client.setGainIndex(_this->gain);
@ -230,9 +228,9 @@ private:
config.release(true);
}
ImGui::LeftLabel("PPM Correction");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::InputInt(CONCAT("##_rtltcp_ppm_", _this->name), &_this->ppm, 1, 10)) {
SmGui::LeftLabel("PPM Correction");
SmGui::FillWidth();
if (SmGui::InputInt(CONCAT("##_rtltcp_ppm_", _this->name), &_this->ppm, 1, 10)) {
if (_this->running) {
_this->client.setPPM(_this->ppm);
}
@ -241,9 +239,9 @@ private:
config.release(true);
}
if (_this->tunerAGC) { style::beginDisabled(); }
ImGui::SetNextItemWidth(menuWidth);
if (ImGui::SliderInt(CONCAT("##_gain_select_", _this->name), &_this->gain, 0, 28, "")) {
if (_this->tunerAGC) { SmGui::BeginDisabled(); }
SmGui::FillWidth();
if (SmGui::SliderInt(CONCAT("##_gain_select_", _this->name), &_this->gain, 0, 28, SmGui::FMT_STR_NONE)) {
if (_this->running) {
_this->client.setGainIndex(_this->gain);
}
@ -251,9 +249,9 @@ private:
config.conf["gainIndex"] = _this->gain;
config.release(true);
}
if (_this->tunerAGC) { style::endDisabled(); }
if (_this->tunerAGC) { SmGui::EndDisabled(); }
if (ImGui::Checkbox(CONCAT("Bias-T##_biast_select_", _this->name), &_this->biasTee)) {
if (SmGui::Checkbox(CONCAT("Bias-T##_biast_select_", _this->name), &_this->biasTee)) {
if (_this->running) {
_this->client.setBiasTee(_this->biasTee);
}
@ -262,7 +260,7 @@ private:
config.release(true);
}
if (ImGui::Checkbox(CONCAT("Offset Tuning##_biast_select_", _this->name), &_this->offsetTuning)) {
if (SmGui::Checkbox(CONCAT("Offset Tuning##_biast_select_", _this->name), &_this->offsetTuning)) {
if (_this->running) {
_this->client.setOffsetTuning(_this->offsetTuning);
}
@ -271,7 +269,7 @@ private:
config.release(true);
}
if (ImGui::Checkbox("RTL AGC", &_this->rtlAGC)) {
if (SmGui::Checkbox("RTL AGC", &_this->rtlAGC)) {
if (_this->running) {
_this->client.setAGCMode(_this->rtlAGC);
if (!_this->rtlAGC) {
@ -283,7 +281,8 @@ private:
config.release(true);
}
if (ImGui::Checkbox("Tuner AGC", &_this->tunerAGC)) {
SmGui::ForceSync();
if (SmGui::Checkbox("Tuner AGC", &_this->tunerAGC)) {
if (_this->running) {
_this->client.setGainMode(!_this->tunerAGC);
if (!_this->tunerAGC) {

View File

@ -29,6 +29,8 @@ public:
AirspyHFSourceModule(std::string name) {
this->name = name;
if (options::opts.serverMode) { return; }
sampleRate = 768000.0;
handler.ctx = this;

View File

@ -8,7 +8,7 @@
#include <config.h>
#include <options.h>
#include <sdrplay_api.h>
#include <gui/smgui.h>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
@ -697,14 +697,12 @@ private:
static void menuHandler(void* ctx) {
SDRPlaySourceModule* _this = (SDRPlaySourceModule*)ctx;
float menuWidth = ImGui::GetContentRegionAvailWidth();
if (_this->running) { style::beginDisabled(); }
if (_this->running) { SmGui::BeginDisabled(); }
ImGui::SetNextItemWidth(menuWidth);
if (ImGui::Combo(CONCAT("##sdrplay_dev", _this->name), &_this->devId, _this->devListTxt.c_str())) {
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Combo(CONCAT("##sdrplay_dev", _this->name), &_this->devId, _this->devListTxt.c_str())) {
_this->selectById(_this->devId);
config.acquire();
config.conf["device"] = _this->devNameList[_this->devId];
@ -712,7 +710,7 @@ private:
}
if (_this->ifModeId == 0) {
if (ImGui::Combo(CONCAT("##sdrplay_sr", _this->name), &_this->srId, sampleRatesTxt)) {
if (SmGui::Combo(CONCAT("##sdrplay_sr", _this->name), &_this->srId, sampleRatesTxt)) {
_this->sampleRate = sampleRates[_this->srId];
if (_this->bandwidthId == 8) {
_this->bandwidth = preferedBandwidth[_this->srId];
@ -723,15 +721,16 @@ private:
config.release(true);
}
ImGui::SameLine();
float refreshBtnWdith = menuWidth - ImGui::GetCursorPosX();
if (ImGui::Button(CONCAT("Refresh##sdrplay_refresh", _this->name), ImVec2(refreshBtnWdith, 0))) {
SmGui::SameLine();
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Button(CONCAT("Refresh##sdrplay_refresh", _this->name))) {
_this->refresh();
_this->selectByName(_this->selectedName);
}
ImGui::SetNextItemWidth(menuWidth);
if (ImGui::Combo(CONCAT("##sdrplay_bw", _this->name), &_this->bandwidthId, bandwidthsTxt)) {
SmGui::FillWidth();
if (SmGui::Combo(CONCAT("##sdrplay_bw", _this->name), &_this->bandwidthId, bandwidthsTxt)) {
_this->bandwidth = (_this->bandwidthId == 8) ? preferedBandwidth[_this->srId] : bandwidths[_this->bandwidthId];
if (_this->running) {
_this->channelParams->tunerParams.bwType = _this->bandwidth;
@ -743,16 +742,18 @@ private:
}
}
else {
if (ImGui::Button(CONCAT("Refresh##sdrplay_refresh", _this->name), ImVec2(menuWidth, 0))) {
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Button(CONCAT("Refresh##sdrplay_refresh", _this->name))) {
_this->refresh();
_this->selectByName(_this->selectedName);
}
}
ImGui::Text("IF Mode");
ImGui::SameLine();
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo(CONCAT("##sdrplay_ifmode", _this->name), &_this->ifModeId, ifModeTxt)) {
SmGui::LeftLabel("IF Mode");
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Combo(CONCAT("##sdrplay_ifmode", _this->name), &_this->ifModeId, ifModeTxt)) {
if (_this->ifModeId != 0) {
_this->bandwidth = ifModes[_this->ifModeId].bw;
_this->sampleRate = ifModes[_this->ifModeId].effectiveSamplerate;
@ -770,13 +771,12 @@ private:
config.release(true);
}
if (_this->running) { style::endDisabled(); }
if (_this->running) { SmGui::EndDisabled(); }
if (_this->selectedName != "") {
ImGui::PushItemWidth(menuWidth - ImGui::CalcTextSize("LNA Gain").x - 10);
ImGui::LeftLabel("LNA Gain");
float pos = ImGui::GetCursorPosX();
if (ImGui::SliderInt(CONCAT("##sdrplay_lna_gain", _this->name), &_this->lnaGain, _this->lnaSteps - 1, 0, "")) {
SmGui::LeftLabel("LNA Gain");
SmGui::FillWidth();
if (SmGui::SliderInt(CONCAT("##sdrplay_lna_gain", _this->name), &_this->lnaGain, _this->lnaSteps - 1, 0, SmGui::FMT_STR_NONE)) {
if (_this->running) {
_this->channelParams->tunerParams.gain.LNAstate = _this->lnaGain;
sdrplay_api_Update(_this->openDev.dev, _this->openDev.tuner, sdrplay_api_Update_Tuner_Gr, sdrplay_api_Update_Ext1_None);
@ -786,10 +786,10 @@ private:
config.release(true);
}
if (_this->agc > 0) { style::beginDisabled(); }
ImGui::LeftLabel("IF Gain");
ImGui::SetCursorPosX(pos);
if (ImGui::SliderInt(CONCAT("##sdrplay_gain", _this->name), &_this->gain, 59, 20, "")) {
if (_this->agc > 0) { SmGui::BeginDisabled(); }
SmGui::LeftLabel("IF Gain");
SmGui::FillWidth();
if (SmGui::SliderInt(CONCAT("##sdrplay_gain", _this->name), &_this->gain, 59, 20, SmGui::FMT_STR_NONE)) {
if (_this->running) {
_this->channelParams->tunerParams.gain.gRdB = _this->gain;
sdrplay_api_Update(_this->openDev.dev, _this->openDev.tuner, sdrplay_api_Update_Tuner_Gr, sdrplay_api_Update_Ext1_None);
@ -798,8 +798,7 @@ private:
config.conf["devices"][_this->selectedName]["ifGain"] = _this->gain;
config.release(true);
}
ImGui::PopItemWidth();
if (_this->agc > 0) { style::endDisabled(); }
if (_this->agc > 0) { SmGui::EndDisabled(); }
if (_this->agcParamEdit) {
@ -831,7 +830,8 @@ private:
}
}
if (ImGui::Checkbox(CONCAT("IF AGC##sdrplay_agc", _this->name), &_this->agc)) {
SmGui::ForceSync();
if (SmGui::Checkbox(CONCAT("IF AGC##sdrplay_agc", _this->name), &_this->agc)) {
if (_this->running) {
_this->channelParams->ctrlParams.agc.enable = _this->agc ? sdrplay_api_AGC_CTRL_EN : sdrplay_api_AGC_DISABLE;
if (_this->agc) {
@ -852,8 +852,10 @@ private:
config.conf["devices"][_this->selectedName]["agc"] = _this->agc;
config.release(true);
}
ImGui::SameLine();
if (ImGui::Button(CONCAT("Parameters##sdrplay_agc_edit_btn", _this->name), ImVec2(menuWidth - ImGui::GetCursorPosX(), 0))) {
SmGui::SameLine();
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Button(CONCAT("Parameters##sdrplay_agc_edit_btn", _this->name))) {
_this->agcParamEdit = true;
_this->_agcAttack = _this->agcAttack;
_this->_agcDecay = _this->agcDecay;
@ -864,100 +866,101 @@ private:
switch (_this->openDev.hwVer) {
case SDRPLAY_RSP1_ID:
_this->RSP1Menu(menuWidth);
_this->RSP1Menu();
break;
case SDRPLAY_RSP1A_ID:
_this->RSP1AMenu(menuWidth);
_this->RSP1AMenu();
break;
case SDRPLAY_RSP2_ID:
_this->RSP2Menu(menuWidth);
_this->RSP2Menu();
break;
case SDRPLAY_RSPduo_ID:
_this->RSPduoMenu(menuWidth);
_this->RSPduoMenu();
break;
case SDRPLAY_RSPdx_ID:
_this->RSPdxMenu(menuWidth);
_this->RSPdxMenu();
break;
default:
_this->RSPUnsupportedMenu(menuWidth);
_this->RSPUnsupportedMenu();
break;
}
}
else {
ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "No device available");
SmGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "No device available");
}
}
bool agcParamMenu(bool& valid) {
bool open = true;
gui::mainWindow.lockWaterfallControls = true;
ImGui::OpenPopup("Edit##sdrplay_source_edit_agc_params_");
if (ImGui::BeginPopup("Edit##sdrplay_source_edit_agc_params_", ImGuiWindowFlags_NoResize)) {
SmGui::OpenPopup("Edit##sdrplay_source_edit_agc_params_");
if (SmGui::BeginPopup("Edit##sdrplay_source_edit_agc_params_", ImGuiWindowFlags_NoResize)) {
if (SmGui::BeginTable(("sdrplay_source_agc_param_tbl" + name).c_str(), 2)) {
SmGui::TableNextRow();
SmGui::TableSetColumnIndex(0);
SmGui::LeftLabel("Attack");
SmGui::TableSetColumnIndex(1);
SmGui::SetNextItemWidth(100);
SmGui::InputInt("ms##sdrplay_source_agc_attack", &_agcAttack);
_agcAttack = std::clamp<int>(_agcAttack, 0, 65535);
ImGui::BeginTable(("sdrplay_source_agc_param_tbl" + name).c_str(), 2);
SmGui::TableNextRow();
SmGui::TableSetColumnIndex(0);
SmGui::LeftLabel("Decay");
SmGui::TableSetColumnIndex(1);
SmGui::SetNextItemWidth(100);
SmGui::InputInt("ms##sdrplay_source_agc_decay", &_agcDecay);
_agcDecay = std::clamp<int>(_agcDecay, 0, 65535);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::LeftLabel("Attack");
ImGui::TableSetColumnIndex(1);
ImGui::SetNextItemWidth(100);
ImGui::InputInt("ms##sdrplay_source_agc_attack", &_agcAttack);
_agcAttack = std::clamp<int>(_agcAttack, 0, 65535);
SmGui::TableNextRow();
SmGui::TableSetColumnIndex(0);
SmGui::LeftLabel("Decay Delay");
SmGui::TableSetColumnIndex(1);
SmGui::SetNextItemWidth(100);
SmGui::InputInt("ms##sdrplay_source_agc_decay_delay", &_agcDecayDelay);
_agcDecayDelay = std::clamp<int>(_agcDecayDelay, 0, 65535);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::LeftLabel("Decay");
ImGui::TableSetColumnIndex(1);
ImGui::SetNextItemWidth(100);
ImGui::InputInt("ms##sdrplay_source_agc_decay", &_agcDecay);
_agcDecay = std::clamp<int>(_agcDecay, 0, 65535);
SmGui::TableNextRow();
SmGui::TableSetColumnIndex(0);
SmGui::LeftLabel("Decay Threshold");
SmGui::TableSetColumnIndex(1);
SmGui::SetNextItemWidth(100);
SmGui::InputInt("dB##sdrplay_source_agc_decay_thresh", &_agcDecayThreshold);
_agcDecayThreshold = std::clamp<int>(_agcDecayThreshold, 0, 100);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::LeftLabel("Decay Delay");
ImGui::TableSetColumnIndex(1);
ImGui::SetNextItemWidth(100);
ImGui::InputInt("ms##sdrplay_source_agc_decay_delay", &_agcDecayDelay);
_agcDecayDelay = std::clamp<int>(_agcDecayDelay, 0, 65535);
SmGui::TableNextRow();
SmGui::TableSetColumnIndex(0);
SmGui::LeftLabel("Setpoint");
SmGui::TableSetColumnIndex(1);
SmGui::SetNextItemWidth(100);
SmGui::InputInt("dBFS##sdrplay_source_agc_setpoint", &_agcSetPoint);
_agcSetPoint = std::clamp<int>(_agcSetPoint, -60, -20);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::LeftLabel("Decay Threshold");
ImGui::TableSetColumnIndex(1);
ImGui::SetNextItemWidth(100);
ImGui::InputInt("dB##sdrplay_source_agc_decay_thresh", &_agcDecayThreshold);
_agcDecayThreshold = std::clamp<int>(_agcDecayThreshold, 0, 100);
SmGui::EndTable();
}
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::LeftLabel("Setpoint");
ImGui::TableSetColumnIndex(1);
ImGui::SetNextItemWidth(100);
ImGui::InputInt("dBFS##sdrplay_source_agc_setpoint", &_agcSetPoint);
_agcSetPoint = std::clamp<int>(_agcSetPoint, -60, -20);
ImGui::EndTable();
if (ImGui::Button("Apply")) {
SmGui::ForceSync();
if (SmGui::Button("Apply")) {
open = false;
valid = true;
}
ImGui::SameLine();
if (ImGui::Button("Cancel")) {
SmGui::SameLine();
SmGui::ForceSync();
if (SmGui::Button("Cancel")) {
open = false;
valid = false;
}
ImGui::EndPopup();
SmGui::EndPopup();
}
return open;
}
void RSP1Menu(float menuWidth) {
void RSP1Menu() {
// No options?
}
void RSP1AMenu(float menuWidth) {
if (ImGui::Checkbox(CONCAT("FM Notch##sdrplay_rsp1a_fmnotch", name), &rsp1a_fmNotch)) {
void RSP1AMenu() {
if (SmGui::Checkbox(CONCAT("FM Notch##sdrplay_rsp1a_fmnotch", name), &rsp1a_fmNotch)) {
if (running) {
openDevParams->devParams->rsp1aParams.rfNotchEnable = rsp1a_fmNotch;
sdrplay_api_Update(openDev.dev, openDev.tuner, sdrplay_api_Update_Rsp1a_RfNotchControl, sdrplay_api_Update_Ext1_None);
@ -966,7 +969,7 @@ private:
config.conf["devices"][selectedName]["fmNotch"] = rsp1a_fmNotch;
config.release(true);
}
if (ImGui::Checkbox(CONCAT("DAB Notch##sdrplay_rsp1a_dabnotch", name), &rsp1a_dabNotch)) {
if (SmGui::Checkbox(CONCAT("DAB Notch##sdrplay_rsp1a_dabnotch", name), &rsp1a_dabNotch)) {
if (running) {
openDevParams->devParams->rsp1aParams.rfNotchEnable = rsp1a_dabNotch;
sdrplay_api_Update(openDev.dev, openDev.tuner, sdrplay_api_Update_Rsp1a_RfDabNotchControl, sdrplay_api_Update_Ext1_None);
@ -975,7 +978,7 @@ private:
config.conf["devices"][selectedName]["dabNotch"] = rsp1a_dabNotch;
config.release(true);
}
if (ImGui::Checkbox(CONCAT("Bias-T##sdrplay_rsp1a_biast", name), &rsp1a_biasT)) {
if (SmGui::Checkbox(CONCAT("Bias-T##sdrplay_rsp1a_biast", name), &rsp1a_biasT)) {
if (running) {
channelParams->rsp1aTunerParams.biasTEnable = rsp1a_biasT;
sdrplay_api_Update(openDev.dev, openDev.tuner, sdrplay_api_Update_Rsp1a_BiasTControl, sdrplay_api_Update_Ext1_None);
@ -986,10 +989,10 @@ private:
}
}
void RSP2Menu(float menuWidth) {
ImGui::LeftLabel("Antenna");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo(CONCAT("##sdrplay_rsp2_ant", name), &rsp2_antennaPort, rsp2_antennaPortsTxt)) {
void RSP2Menu() {
SmGui::LeftLabel("Antenna");
SmGui::FillWidth();
if (SmGui::Combo(CONCAT("##sdrplay_rsp2_ant", name), &rsp2_antennaPort, rsp2_antennaPortsTxt)) {
if (running) {
channelParams->rsp2TunerParams.antennaSel = rsp2_antennaPorts[rsp2_antennaPort];
channelParams->rsp2TunerParams.amPortSel = (rsp2_antennaPort == 2) ? sdrplay_api_Rsp2_AMPORT_1 : sdrplay_api_Rsp2_AMPORT_2;
@ -1000,7 +1003,7 @@ private:
config.conf["devices"][selectedName]["antenna"] = rsp2_antennaPort;
config.release(true);
}
if (ImGui::Checkbox(CONCAT("MW/FM Notch##sdrplay_rsp2_notch", name), &rsp2_notch)) {
if (SmGui::Checkbox(CONCAT("MW/FM Notch##sdrplay_rsp2_notch", name), &rsp2_notch)) {
if (running) {
channelParams->rsp2TunerParams.rfNotchEnable = rsp2_notch;
sdrplay_api_Update(openDev.dev, openDev.tuner, sdrplay_api_Update_Rsp2_RfNotchControl, sdrplay_api_Update_Ext1_None);
@ -1009,7 +1012,7 @@ private:
config.conf["devices"][selectedName]["notch"] = rsp2_notch;
config.release(true);
}
if (ImGui::Checkbox(CONCAT("Bias-T##sdrplay_rsp2_biast", name), &rsp2_biasT)) {
if (SmGui::Checkbox(CONCAT("Bias-T##sdrplay_rsp2_biast", name), &rsp2_biasT)) {
if (running) {
channelParams->rsp2TunerParams.biasTEnable = rsp2_biasT;
sdrplay_api_Update(openDev.dev, openDev.tuner, sdrplay_api_Update_Rsp2_BiasTControl, sdrplay_api_Update_Ext1_None);
@ -1020,11 +1023,10 @@ private:
}
}
void RSPduoMenu(float menuWidth) {
ImGui::LeftLabel("Antenna");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo(CONCAT("##sdrplay_rspduo_ant", name), &rspduo_antennaPort, rspduo_antennaPortsTxt)) {
void RSPduoMenu() {
SmGui::LeftLabel("Antenna");
SmGui::FillWidth();
if (SmGui::Combo(CONCAT("##sdrplay_rspduo_ant", name), &rspduo_antennaPort, rspduo_antennaPortsTxt)) {
if (running) {
rspDuoSelectAntennaPort(rspduo_antennaPort);
}
@ -1032,7 +1034,7 @@ private:
config.conf["devices"][selectedName]["antenna"] = rspduo_antennaPort;
config.release(true);
}
if (ImGui::Checkbox(CONCAT("FM Notch##sdrplay_rspduo_notch", name), &rspduo_fmNotch)) {
if (SmGui::Checkbox(CONCAT("FM Notch##sdrplay_rspduo_notch", name), &rspduo_fmNotch)) {
if (running) {
channelParams->rspDuoTunerParams.rfNotchEnable = rspduo_fmNotch;
sdrplay_api_Update(openDev.dev, openDev.tuner, sdrplay_api_Update_RspDuo_RfNotchControl, sdrplay_api_Update_Ext1_None);
@ -1041,7 +1043,7 @@ private:
config.conf["devices"][selectedName]["fmNotch"] = rspduo_fmNotch;
config.release(true);
}
if (ImGui::Checkbox(CONCAT("DAB Notch##sdrplay_rspduo_dabnotch", name), &rspduo_dabNotch)) {
if (SmGui::Checkbox(CONCAT("DAB Notch##sdrplay_rspduo_dabnotch", name), &rspduo_dabNotch)) {
if (running) {
channelParams->rspDuoTunerParams.rfDabNotchEnable = rspduo_dabNotch;
sdrplay_api_Update(openDev.dev, openDev.tuner, sdrplay_api_Update_RspDuo_RfDabNotchControl, sdrplay_api_Update_Ext1_None);
@ -1050,7 +1052,7 @@ private:
config.conf["devices"][selectedName]["dabNotch"] = rspduo_dabNotch;
config.release(true);
}
if (ImGui::Checkbox(CONCAT("AM Notch##sdrplay_rspduo_dabnotch", name), &rspduo_amNotch)) {
if (SmGui::Checkbox(CONCAT("AM Notch##sdrplay_rspduo_dabnotch", name), &rspduo_amNotch)) {
if (running) {
channelParams->rspDuoTunerParams.tuner1AmNotchEnable = rspduo_amNotch;
sdrplay_api_Update(openDev.dev, openDev.tuner, sdrplay_api_Update_RspDuo_Tuner1AmNotchControl, sdrplay_api_Update_Ext1_None);
@ -1059,7 +1061,7 @@ private:
config.conf["devices"][selectedName]["amNotch"] = rspduo_amNotch;
config.release(true);
}
if (ImGui::Checkbox(CONCAT("Bias-T##sdrplay_rspduo_biast", name), &rspduo_biasT)) {
if (SmGui::Checkbox(CONCAT("Bias-T##sdrplay_rspduo_biast", name), &rspduo_biasT)) {
if (running) {
channelParams->rspDuoTunerParams.biasTEnable = rspduo_biasT;
sdrplay_api_Update(openDev.dev, openDev.tuner, sdrplay_api_Update_RspDuo_BiasTControl, sdrplay_api_Update_Ext1_None);
@ -1070,10 +1072,10 @@ private:
}
}
void RSPdxMenu(float menuWidth) {
ImGui::LeftLabel("Antenna");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo(CONCAT("##sdrplay_rspdx_ant", name), &rspdx_antennaPort, rspdx_antennaPortsTxt)) {
void RSPdxMenu() {
SmGui::LeftLabel("Antenna");
SmGui::FillWidth();
if (SmGui::Combo(CONCAT("##sdrplay_rspdx_ant", name), &rspdx_antennaPort, rspdx_antennaPortsTxt)) {
if (running) {
openDevParams->devParams->rspDxParams.antennaSel = rspdx_antennaPorts[rspdx_antennaPort];
sdrplay_api_Update(openDev.dev, openDev.tuner, sdrplay_api_Update_None, sdrplay_api_Update_RspDx_AntennaControl);
@ -1083,7 +1085,7 @@ private:
config.release(true);
}
if (ImGui::Checkbox(CONCAT("FM Notch##sdrplay_rspdx_fmnotch", name), &rspdx_fmNotch)) {
if (SmGui::Checkbox(CONCAT("FM Notch##sdrplay_rspdx_fmnotch", name), &rspdx_fmNotch)) {
if (running) {
openDevParams->devParams->rspDxParams.rfNotchEnable = rspdx_fmNotch;
sdrplay_api_Update(openDev.dev, openDev.tuner, sdrplay_api_Update_None, sdrplay_api_Update_RspDx_RfNotchControl);
@ -1092,7 +1094,7 @@ private:
config.conf["devices"][selectedName]["fmNotch"] = rspdx_fmNotch;
config.release(true);
}
if (ImGui::Checkbox(CONCAT("DAB Notch##sdrplay_rspdx_dabnotch", name), &rspdx_dabNotch)) {
if (SmGui::Checkbox(CONCAT("DAB Notch##sdrplay_rspdx_dabnotch", name), &rspdx_dabNotch)) {
if (running) {
openDevParams->devParams->rspDxParams.rfDabNotchEnable = rspdx_dabNotch;
sdrplay_api_Update(openDev.dev, openDev.tuner, sdrplay_api_Update_None, sdrplay_api_Update_RspDx_RfDabNotchControl);
@ -1101,7 +1103,7 @@ private:
config.conf["devices"][selectedName]["dabNotch"] = rspdx_dabNotch;
config.release(true);
}
if (ImGui::Checkbox(CONCAT("Bias-T##sdrplay_rspdx_biast", name), &rspdx_biasT)) {
if (SmGui::Checkbox(CONCAT("Bias-T##sdrplay_rspdx_biast", name), &rspdx_biasT)) {
if (running) {
openDevParams->devParams->rspDxParams.biasTEnable = rspdx_biasT;
sdrplay_api_Update(openDev.dev, openDev.tuner, sdrplay_api_Update_None, sdrplay_api_Update_RspDx_BiasTControl);
@ -1112,8 +1114,8 @@ private:
}
}
void RSPUnsupportedMenu(float menuWidth) {
ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "Device currently unsupported");
void RSPUnsupportedMenu() {
SmGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "Device currently unsupported");
}
static void streamCB(short* xi, short* xq, sdrplay_api_StreamCbParamsT* params,

View File

@ -0,0 +1,25 @@
cmake_minimum_required(VERSION 3.13)
project(sdrpp_server_source)
file(GLOB SRC "src/*.cpp")
add_library(sdrpp_server_source SHARED ${SRC})
target_link_libraries(sdrpp_server_source PRIVATE sdrpp_core)
set_target_properties(sdrpp_server_source PROPERTIES PREFIX "")
target_include_directories(sdrpp_server_source PRIVATE "src/")
if (MSVC)
target_compile_options(sdrpp_server_source PRIVATE /O2 /Ob2 /std:c++17 /EHsc)
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(sdrpp_server_source PRIVATE -O3 -std=c++17 -Wno-unused-command-line-argument -undefined dynamic_lookup)
else ()
target_compile_options(sdrpp_server_source PRIVATE -O3 -std=c++17)
endif ()
if(WIN32)
target_link_libraries(sdrpp_server_source PRIVATE wsock32 ws2_32)
endif()
# Install directives
install(TARGETS sdrpp_server_source DESTINATION lib/sdrpp/plugins)

View File

@ -0,0 +1,279 @@
#include "sdrpp_server_client.h"
#include <imgui.h>
#include <spdlog/spdlog.h>
#include <module.h>
#include <gui/gui.h>
#include <signal_path/signal_path.h>
#include <core.h>
#include <gui/style.h>
#include <config.h>
#include <options.h>
#include <gui/widgets/stepped_slider.h>
#include <utils/optionlist.h>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
SDRPP_MOD_INFO{
/* Name: */ "sdrpp_server_source",
/* Description: */ "SDR++ Server source module for SDR++",
/* Author: */ "Ryzerth",
/* Version: */ 0, 1, 0,
/* Max instances */ 1
};
ConfigManager config;
class SDRPPServerSourceModule : public ModuleManager::Instance {
public:
SDRPPServerSourceModule(std::string name) {
this->name = name;
// Yeah no server-ception, sorry...
if (options::opts.serverMode) { return; }
// Initialize lists
sampleTypeList.define("Int8", dsp::PCM_TYPE_I8);
sampleTypeList.define("Int16", dsp::PCM_TYPE_I16);
sampleTypeList.define("Float32", dsp::PCM_TYPE_F32);
sampleTypeId = sampleTypeList.valueId(dsp::PCM_TYPE_I16);
handler.ctx = this;
handler.selectHandler = menuSelected;
handler.deselectHandler = menuDeselected;
handler.menuHandler = menuHandler;
handler.startHandler = start;
handler.stopHandler = stop;
handler.tuneHandler = tune;
handler.stream = &stream;
// Load config
config.acquire();
std::string hostStr = config.conf["hostname"];
strcpy(hostname, hostStr.c_str());
port = config.conf["port"];
config.release();
sigpath::sourceManager.registerSource("SDR++ Server", &handler);
}
~SDRPPServerSourceModule() {
stop(this);
sigpath::sourceManager.unregisterSource("SDR++ Server");
}
void postInit() {}
void enable() {
enabled = true;
}
void disable() {
enabled = false;
}
bool isEnabled() {
return enabled;
}
private:
std::string getBandwdithScaled(double bw) {
char buf[1024];
if (bw >= 1000000.0) {
sprintf(buf, "%.1lfMHz", bw / 1000000.0);
}
else if (bw >= 1000.0) {
sprintf(buf, "%.1lfKHz", bw / 1000.0);
}
else {
sprintf(buf, "%.1lfHz", bw);
}
return std::string(buf);
}
static void menuSelected(void* ctx) {
SDRPPServerSourceModule* _this = (SDRPPServerSourceModule*)ctx;
if (_this->client) {
core::setInputSampleRate(_this->client->getSampleRate());
}
gui::mainWindow.playButtonLocked = !(_this->client && _this->client->isOpen());
spdlog::info("SDRPPServerSourceModule '{0}': Menu Select!", _this->name);
}
static void menuDeselected(void* ctx) {
SDRPPServerSourceModule* _this = (SDRPPServerSourceModule*)ctx;
gui::mainWindow.playButtonLocked = false;
spdlog::info("SDRPPServerSourceModule '{0}': Menu Deselect!", _this->name);
}
static void start(void* ctx) {
SDRPPServerSourceModule* _this = (SDRPPServerSourceModule*)ctx;
if (_this->running) { return; }
// TODO: Set configuration here
if (_this->client) { _this->client->start(); }
_this->running = true;
spdlog::info("SDRPPServerSourceModule '{0}': Start!", _this->name);
}
static void stop(void* ctx) {
SDRPPServerSourceModule* _this = (SDRPPServerSourceModule*)ctx;
if (!_this->running) { return; }
if (_this->client) { _this->client->stop(); }
_this->running = false;
spdlog::info("SDRPPServerSourceModule '{0}': Stop!", _this->name);
}
static void tune(double freq, void* ctx) {
SDRPPServerSourceModule* _this = (SDRPPServerSourceModule*)ctx;
if (_this->running && _this->client) {
_this->client->setFrequency(freq);
}
_this->freq = freq;
spdlog::info("SDRPPServerSourceModule '{0}': Tune: {1}!", _this->name, freq);
}
static void menuHandler(void* ctx) {
SDRPPServerSourceModule* _this = (SDRPPServerSourceModule*)ctx;
float menuWidth = ImGui::GetContentRegionAvailWidth();
bool connected = (_this->client && _this->client->isOpen());
gui::mainWindow.playButtonLocked = !connected;
if (connected) { style::beginDisabled(); }
if (ImGui::InputText(CONCAT("##sdrpp_srv_srv_host_", _this->name), _this->hostname, 1023)) {
config.acquire();
config.conf["hostname"] = _this->hostname;
config.release(true);
}
ImGui::SameLine();
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::InputInt(CONCAT("##sdrpp_srv_srv_port_", _this->name), &_this->port, 0, 0)) {
config.acquire();
config.conf["port"] = _this->port;
config.release(true);
}
if (connected) { style::endDisabled(); }
if (_this->running) { style::beginDisabled(); }
if (!connected && ImGui::Button("Connect##sdrpp_srv_source", ImVec2(menuWidth, 0))) {
try {
if (_this->client) { _this->client.reset(); }
_this->client = server::connect(_this->hostname, _this->port, &_this->stream);
_this->deviceInit();
}
catch (std::exception e) {
spdlog::error("Could not connect to SDR: {0}", e.what());
}
}
else if (connected && ImGui::Button("Disconnect##sdrpp_srv_source", ImVec2(menuWidth, 0))) {
_this->client->close();
}
if (_this->running) { style::endDisabled(); }
if (connected) {
ImGui::LeftLabel("Sample type");
ImGui::FillWidth();
if (ImGui::Combo("##sdrpp_srv_source_samp_type", &_this->sampleTypeId, _this->sampleTypeList.txt)) {
_this->client->setSampleType(_this->sampleTypeList[_this->sampleTypeId]);
// Save config
config.acquire();
config.conf["servers"][_this->devConfName]["sampleType"] = _this->sampleTypeList.key(_this->sampleTypeId);
config.release(true);
}
bool dummy = false;
style::beginDisabled();
ImGui::Checkbox("Compression", &dummy);
dummy = true;
ImGui::Checkbox("Full IQ", &dummy);
style::endDisabled();
// Calculate datarate
_this->frametimeCounter += ImGui::GetIO().DeltaTime;
if (_this->frametimeCounter >= 0.2f) {
_this->datarate = ((float)_this->client->bytes / (_this->frametimeCounter * 1024.0f * 1024.0f)) * 8;
_this->frametimeCounter = 0;
_this->client->bytes = 0;
}
ImGui::Text("Status:");
ImGui::SameLine();
ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "Connected (%.3f Mbit/s)", _this->datarate);
ImGui::CollapsingHeader("Source [REMOTE]", ImGuiTreeNodeFlags_DefaultOpen);
_this->client->showMenu();
}
else {
ImGui::Text("Status:");
ImGui::SameLine();
ImGui::Text("Not connected (--.--- Mbit/s)");
}
}
void deviceInit() {
// Generate the config name
char buf[4096];
sprintf(buf, "%s:%05d", hostname, port);
devConfName = buf;
// Load settings
sampleTypeId = sampleTypeList.valueId(dsp::PCM_TYPE_I16);
if (config.conf["servers"][devConfName].contains("sampleType")) {
std::string key = config.conf["servers"][devConfName]["sampleType"];
if (sampleTypeList.keyExists(key)) { sampleTypeId = sampleTypeList.keyId(key); }
}
// Set settings
client->setSampleType(sampleTypeList[sampleTypeId]);
}
std::string name;
bool enabled = true;
bool running = false;
double freq;
float datarate = 0;
float frametimeCounter = 0;
char hostname[1024];
int port = 50000;
std::string devConfName = "";
dsp::stream<dsp::complex_t> stream;
SourceManager::SourceHandler handler;
OptionList<std::string, dsp::PCMType> sampleTypeList;
int sampleTypeId;
server::Client client;
};
MOD_EXPORT void _INIT_() {
json def = json({});
def["hostname"] = "localhost";
def["port"] = 5259;
def["servers"] = json::object();
config.setPath(options::opts.root + "/sdrpp_server_source_config.json");
config.load(def);
config.enableAutoSave();
}
MOD_EXPORT ModuleManager::Instance* _CREATE_INSTANCE_(std::string name) {
return new SDRPPServerSourceModule(name);
}
MOD_EXPORT void _DELETE_INSTANCE_(ModuleManager::Instance* instance) {
delete (SDRPPServerSourceModule*)instance;
}
MOD_EXPORT void _END_() {
config.disableAutoSave();
config.save();
}

View File

@ -0,0 +1,233 @@
#include "sdrpp_server_client.h"
#include <volk/volk.h>
#include <cstring>
#include <spdlog/spdlog.h>
#include <core.h>
using namespace std::chrono_literals;
namespace server {
ClientClass::ClientClass(net::Conn conn, dsp::stream<dsp::complex_t>* out) {
client = std::move(conn);
output = out;
// Allocate buffers
rbuffer = new uint8_t[SERVER_MAX_PACKET_SIZE];
sbuffer = new uint8_t[SERVER_MAX_PACKET_SIZE];
// Initialize headers
r_pkt_hdr = (PacketHeader*)rbuffer;
r_pkt_data = &rbuffer[sizeof(PacketHeader)];
r_cmd_hdr = (CommandHeader*)r_pkt_data;
r_cmd_data = &rbuffer[sizeof(PacketHeader) + sizeof(CommandHeader)];
s_pkt_hdr = (PacketHeader*)sbuffer;
s_pkt_data = &sbuffer[sizeof(PacketHeader)];
s_cmd_hdr = (CommandHeader*)s_pkt_data;
s_cmd_data = &sbuffer[sizeof(PacketHeader) + sizeof(CommandHeader)];
// Initialize DSP
decomp.init(&decompIn);
link.init(&decomp.out, output);
decomp.start();
link.start();
// Start readers
client->readAsync(sizeof(PacketHeader), rbuffer, tcpHandler, this);
// Default configuration
stop();
// Ask for a UI
getUI();
}
ClientClass::~ClientClass() {
close();
delete[] rbuffer;
delete[] sbuffer;
}
void ClientClass::showMenu() {
std::string diffId = "";
SmGui::DrawListElem diffValue;
bool syncRequired = false;
{
std::lock_guard<std::mutex> lck(dlMtx);
dl.draw(diffId, diffValue, syncRequired);
}
if (!diffId.empty()) {
// Save ID
SmGui::DrawListElem elemId;
elemId.type = SmGui::DRAW_LIST_ELEM_TYPE_STRING;
elemId.str = diffId;
// Encore packet
int size = 0;
s_cmd_data[size++] = syncRequired;
size += SmGui::DrawList::storeItem(elemId, &s_cmd_data[size], SERVER_MAX_PACKET_SIZE - size);
size += SmGui::DrawList::storeItem(diffValue, &s_cmd_data[size], SERVER_MAX_PACKET_SIZE - size);
// Send
if (syncRequired) {
spdlog::warn("Action requires resync");
auto waiter = awaitCommandAck(COMMAND_UI_ACTION);
sendCommand(COMMAND_UI_ACTION, size);
if (waiter->await(PROTOCOL_TIMEOUT_MS)) {
std::lock_guard lck(dlMtx);
dl.load(r_cmd_data, r_pkt_hdr->size - sizeof(PacketHeader) - sizeof(CommandHeader));
}
else {
spdlog::error("Timeout out after asking for UI");
}
waiter->handled();
spdlog::warn("Resync done");
}
else {
spdlog::warn("Action does not require resync");
sendCommand(COMMAND_UI_ACTION, size);
}
}
}
void ClientClass::setFrequency(double freq) {
if (!client || !client->isOpen()) { return; }
*(double*)s_cmd_data = freq;
sendCommand(COMMAND_SET_FREQUENCY, sizeof(double));
auto waiter = awaitCommandAck(COMMAND_SET_FREQUENCY);
waiter->await(PROTOCOL_TIMEOUT_MS);
waiter->handled();
}
double ClientClass::getSampleRate() {
return currentSampleRate;
}
void ClientClass::setSampleType(dsp::PCMType type) {
s_cmd_data[0] = type;
sendCommand(COMMAND_SET_SAMPLE_TYPE, 1);
}
void ClientClass::start() {
if (!client || !client->isOpen()) { return; }
sendCommand(COMMAND_START, 0);
getUI();
}
void ClientClass::stop() {
if (!client || !client->isOpen()) { return; }
sendCommand(COMMAND_STOP, 0);
getUI();
}
void ClientClass::close() {
decomp.stop();
link.stop();
client->close();
}
bool ClientClass::isOpen() {
return client->isOpen();
}
void ClientClass::tcpHandler(int count, uint8_t* buf, void* ctx) {
ClientClass* _this = (ClientClass*)ctx;
// Read the rest of the data (TODO: CHECK SIZE OR SHIT WILL BE FUCKED)
int len = 0;
int read = 0;
int goal = _this->r_pkt_hdr->size - sizeof(PacketHeader);
while (len < goal) {
read = _this->client->read(goal - len, &buf[sizeof(PacketHeader) + len]);
if (read < 0) {
return;
};
len += read;
}
_this->bytes += _this->r_pkt_hdr->size;
if (_this->r_pkt_hdr->type == PACKET_TYPE_COMMAND) {
// TODO: Move to command handler
if (_this->r_cmd_hdr->cmd == COMMAND_SET_SAMPLERATE && _this->r_pkt_hdr->size == sizeof(PacketHeader) + sizeof(CommandHeader) + sizeof(double)) {
_this->currentSampleRate = *(double*)_this->r_cmd_data;
core::setInputSampleRate(_this->currentSampleRate);
}
}
else if (_this->r_pkt_hdr->type == PACKET_TYPE_COMMAND_ACK) {
// Notify waiters
std::vector<PacketWaiter*> toBeRemoved;
for (auto& [waiter, cmd] : _this->commandAckWaiters) {
if (cmd != _this->r_cmd_hdr->cmd) { continue; }
waiter->notify();
toBeRemoved.push_back(waiter);
}
// Remove handled waiters
for (auto& waiter : toBeRemoved) {
_this->commandAckWaiters.erase(waiter);
delete waiter;
}
}
else if (_this->r_pkt_hdr->type == PACKET_TYPE_BASEBAND) {
memcpy(_this->decompIn.writeBuf, &buf[sizeof(PacketHeader)], _this->r_pkt_hdr->size - sizeof(PacketHeader));
_this->decompIn.swap(_this->r_pkt_hdr->size - sizeof(PacketHeader));
}
else if (_this->r_pkt_hdr->type == PACKET_TYPE_ERROR) {
spdlog::error("SDR++ Server Error: {0}", buf[sizeof(PacketHeader)]);
}
else {
spdlog::error("Invalid packet type: {0}", _this->r_pkt_hdr->type);
}
// Restart an async read
_this->client->readAsync(sizeof(PacketHeader), _this->rbuffer, tcpHandler, _this);
}
void ClientClass::getUI() {
auto waiter = awaitCommandAck(COMMAND_GET_UI);
sendCommand(COMMAND_GET_UI, 0);
if (waiter->await(PROTOCOL_TIMEOUT_MS)) {
std::lock_guard lck(dlMtx);
dl.load(r_cmd_data, r_pkt_hdr->size - sizeof(PacketHeader) - sizeof(CommandHeader));
}
else {
spdlog::error("Timeout out after asking for UI");
}
waiter->handled();
}
void ClientClass::sendPacket(PacketType type, int len) {
s_pkt_hdr->type = type;
s_pkt_hdr->size = sizeof(PacketHeader) + len;
client->write(s_pkt_hdr->size, sbuffer);
}
void ClientClass::sendCommand(Command cmd, int len) {
s_cmd_hdr->cmd = cmd;
sendPacket(PACKET_TYPE_COMMAND, sizeof(CommandHeader) + len);
}
void ClientClass::sendCommandAck(Command cmd, int len) {
s_cmd_hdr->cmd = cmd;
sendPacket(PACKET_TYPE_COMMAND_ACK, sizeof(CommandHeader) + len);
}
PacketWaiter* ClientClass::awaitCommandAck(Command cmd) {
PacketWaiter* waiter = new PacketWaiter;
commandAckWaiters[waiter] = cmd;
return waiter;
}
void ClientClass::dHandler(dsp::complex_t *data, int count, void *ctx) {
ClientClass* _this = (ClientClass*)ctx;
memcpy(_this->output->writeBuf, data, count * sizeof(dsp::complex_t));
_this->output->swap(count);
}
Client connect(std::string host, uint16_t port, dsp::stream<dsp::complex_t>* out) {
net::Conn conn = net::connect(host, port);
if (!conn) { return NULL; }
return Client(new ClientClass(std::move(conn), out));
}
}

View File

@ -0,0 +1,134 @@
#pragma once
#include <utils/networking.h>
#include <dsp/stream.h>
#include <dsp/types.h>
#include <atomic>
#include <queue>
#include <server_protocol.h>
#include <atomic>
#include <map>
#include <vector>
#include <dsp/compression.h>
#include <dsp/sink.h>
#include <dsp/link.h>
#define RFSPACE_MAX_SIZE 8192
#define RFSPACE_HEARTBEAT_INTERVAL_MS 1000
#define RFSPACE_TIMEOUT_MS 3000
#define PROTOCOL_TIMEOUT_MS 10000
namespace server {
class PacketWaiter {
public:
bool await(int timeout) {
std::unique_lock lck(readyMtx);
return readyCnd.wait_for(lck, std::chrono::milliseconds(timeout), [=](){ return dataReady; });
}
void handled() {
{
std::lock_guard lck(handledMtx);
dataHandled = true;
}
handledCnd.notify_all();
}
void notify() {
// Tell waiter that data is ready
{
std::lock_guard lck(readyMtx);
dataReady = true;
}
readyCnd.notify_all();
// Wait for waiter to handle the request
{
std::unique_lock lck(readyMtx);
handledCnd.wait(lck, [=](){ return dataHandled; });
}
}
void reset() {
std::lock_guard lck1(readyMtx);
std::lock_guard lck2(handledMtx);
dataReady = false;
dataHandled = false;
}
private:
bool dataReady = false;
bool dataHandled = false;
std::condition_variable readyCnd;
std::condition_variable handledCnd;
std::mutex readyMtx;
std::mutex handledMtx;
};
class ClientClass {
public:
ClientClass(net::Conn conn, dsp::stream<dsp::complex_t>* out);
~ClientClass();
void showMenu();
void setFrequency(double freq);
double getSampleRate();
void setSampleType(dsp::PCMType type);
void start();
void stop();
void close();
bool isOpen();
int bytes = 0;
private:
static void tcpHandler(int count, uint8_t* buf, void* ctx);
void getUI();
void sendPacket(PacketType type, int len);
void sendCommand(Command cmd, int len);
void sendCommandAck(Command cmd, int len);
PacketWaiter* awaitCommandAck(Command cmd);
void commandAckHandled(PacketWaiter* waiter);
std::map<PacketWaiter*, Command> commandAckWaiters;
static void dHandler(dsp::complex_t *data, int count, void *ctx);
net::Conn client;
dsp::stream<uint8_t> decompIn;
dsp::DynamicRangeDecompressor decomp;
dsp::Link<dsp::complex_t> link;
dsp::stream<dsp::complex_t>* output;
uint8_t* rbuffer = NULL;
uint8_t* sbuffer = NULL;
PacketHeader* r_pkt_hdr = NULL;
uint8_t* r_pkt_data = NULL;
CommandHeader* r_cmd_hdr = NULL;
uint8_t* r_cmd_data = NULL;
PacketHeader* s_pkt_hdr = NULL;
uint8_t* s_pkt_data = NULL;
CommandHeader* s_cmd_hdr = NULL;
uint8_t* s_cmd_data = NULL;
SmGui::DrawList dl;
std::mutex dlMtx;
double currentSampleRate = 1000000.0;
};
typedef std::unique_ptr<ClientClass> Client;
Client connect(std::string host, uint16_t port, dsp::stream<dsp::complex_t>* out);
}

View File

@ -11,6 +11,7 @@
#include <core.h>
#include <gui/style.h>
#include <options.h>
#include <gui/smgui.h>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
@ -365,65 +366,66 @@ private:
static void menuHandler(void* ctx) {
SoapyModule* _this = (SoapyModule*)ctx;
float menuWidth = ImGui::GetContentRegionAvailWidth();
// If no device is selected, draw only the refresh button
if (_this->devId < 0) {
if (ImGui::Button(CONCAT("Refresh##_dev_select_", _this->name), ImVec2(menuWidth, 0))) {
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Button(CONCAT("Refresh##_dev_select_", _this->name))) {
_this->refresh();
_this->selectDevice(config.conf["device"]);
}
return;
}
if (_this->running) { style::beginDisabled(); }
if (_this->running) { SmGui::BeginDisabled(); }
ImGui::SetNextItemWidth(menuWidth);
if (ImGui::Combo(CONCAT("##_dev_select_", _this->name), &_this->devId, _this->txtDevList.c_str())) {
SmGui::FillWidth();
SmGui::ForceSync();
if (SmGui::Combo(CONCAT("##_dev_select_", _this->name), &_this->devId, _this->txtDevList.c_str())) {
_this->selectDevice(_this->devList[_this->devId]["label"]);
config.acquire();
config.conf["device"] = _this->devList[_this->devId]["label"];
config.release(true);
}
if (ImGui::Combo(CONCAT("##_sr_select_", _this->name), &_this->srId, _this->txtSrList.c_str())) {
if (SmGui::Combo(CONCAT("##_sr_select_", _this->name), &_this->srId, _this->txtSrList.c_str())) {
_this->selectSampleRate(_this->sampleRates[_this->srId]);
if (_this->bandwidthList.size() > 2 && _this->running && _this->bandwidthList[_this->uiBandwidthId] == -1)
_this->dev->setBandwidth(SOAPY_SDR_RX, _this->channelId, _this->selectBwBySr(_this->sampleRates[_this->srId]));
_this->saveCurrent();
}
ImGui::SameLine();
float refreshBtnWdith = menuWidth - ImGui::GetCursorPosX();
if (ImGui::Button(CONCAT("Refresh##_dev_select_", _this->name), ImVec2(refreshBtnWdith, 0))) {
SmGui::SameLine();
SmGui::FillWidth();
if (SmGui::Button(CONCAT("Refresh##_dev_select_", _this->name))) {
_this->refresh();
_this->selectDevice(config.conf["device"]);
}
if (_this->running) { style::endDisabled(); }
if (_this->running) { SmGui::EndDisabled(); }
if (_this->antennaList.size() > 1) {
ImGui::LeftLabel("Antenna");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo(CONCAT("##_antenna_select_", _this->name), &_this->uiAntennaId, _this->txtAntennaList.c_str())) {
SmGui::LeftLabel("Antenna");
SmGui::FillWidth();
if (SmGui::Combo(CONCAT("##_antenna_select_", _this->name), &_this->uiAntennaId, _this->txtAntennaList.c_str())) {
if (_this->running)
_this->dev->setAntenna(SOAPY_SDR_RX, _this->channelId, _this->antennaList[_this->uiAntennaId]);
_this->saveCurrent();
}
}
float gainNameLen = 0;
float len;
for (auto gain : _this->gainList) {
len = ImGui::CalcTextSize((gain + " gain").c_str()).x;
if (len > gainNameLen) {
gainNameLen = len;
}
}
gainNameLen += 5.0f;
// float gainNameLen = 0;
// float len;
// for (auto gain : _this->gainList) {
// len = ImGui::CalcTextSize((gain + " gain").c_str()).x;
// if (len > gainNameLen) {
// gainNameLen = len;
// }
// }
// gainNameLen += 5.0f;
if (_this->hasAgc) {
if (ImGui::Checkbox((std::string("AGC##_agc_sel_") + _this->name).c_str(), &_this->agc)) {
if (SmGui::Checkbox((std::string("AGC##_agc_sel_") + _this->name).c_str(), &_this->agc)) {
if (_this->running) { _this->dev->setGainMode(SOAPY_SDR_RX, _this->channelId, _this->agc); }
// When disabled, reset the gains
if (!_this->agc) {
@ -441,16 +443,17 @@ private:
char buf[128];
for (auto gain : _this->gainList) {
sprintf(buf, "%s gain", gain.c_str());
ImGui::LeftLabel(buf);
ImGui::SetCursorPosX(gainNameLen);
ImGui::SetNextItemWidth(menuWidth - gainNameLen);
SmGui::LeftLabel(buf);
// ImGui::SetCursorPosX(gainNameLen);
// ImGui::SetNextItemWidth(menuWidth - gainNameLen);
float step = _this->gainRanges[i].step();
bool res;
SmGui::FillWidth();
if (step == 0.0f) {
res = ImGui::SliderFloat((std::string("##_gain_sel_") + _this->name + gain).c_str(), &_this->uiGains[i], _this->gainRanges[i].minimum(), _this->gainRanges[i].maximum());
res = SmGui::SliderFloat((std::string("##_gain_sel_") + _this->name + gain).c_str(), &_this->uiGains[i], _this->gainRanges[i].minimum(), _this->gainRanges[i].maximum());
}
else {
res = ImGui::SliderFloatWithSteps((std::string("##_gain_sel_") + _this->name + gain).c_str(), &_this->uiGains[i], _this->gainRanges[i].minimum(), _this->gainRanges[i].maximum(), step);
res = SmGui::SliderFloatWithSteps((std::string("##_gain_sel_") + _this->name + gain).c_str(), &_this->uiGains[i], _this->gainRanges[i].minimum(), _this->gainRanges[i].maximum(), step);
}
if (res) {
if (_this->running) {
@ -461,9 +464,9 @@ private:
i++;
}
if (_this->bandwidthList.size() > 2) {
ImGui::LeftLabel("Bandwidth");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo(CONCAT("##_bw_select_", _this->name), &_this->uiBandwidthId, _this->txtBwList.c_str())) {
SmGui::LeftLabel("Bandwidth");
SmGui::FillWidth();
if (SmGui::Combo(CONCAT("##_bw_select_", _this->name), &_this->uiBandwidthId, _this->txtBwList.c_str())) {
if (_this->running) {
if (_this->bandwidthList[_this->uiBandwidthId] == -1)
_this->dev->setBandwidth(SOAPY_SDR_RX, _this->channelId, _this->selectBwBySr(_this->sampleRates[_this->srId]));

View File

@ -9,6 +9,7 @@
#include <config.h>
#include <options.h>
#include <gui/widgets/stepped_slider.h>
#include <gui/smgui.h>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
@ -155,28 +156,29 @@ private:
static void menuHandler(void* ctx) {
SpyServerSourceModule* _this = (SpyServerSourceModule*)ctx;
float menuWidth = ImGui::GetContentRegionAvailWidth();
bool connected = (_this->client && _this->client->isOpen());
gui::mainWindow.playButtonLocked = !connected;
if (connected) { style::beginDisabled(); }
if (ImGui::InputText(CONCAT("##_spyserver_srv_host_", _this->name), _this->hostname, 1023)) {
if (connected) { SmGui::BeginDisabled(); }
if (SmGui::InputText(CONCAT("##_spyserver_srv_host_", _this->name), _this->hostname, 1023)) {
config.acquire();
config.conf["hostname"] = _this->hostname;
config.release(true);
}
ImGui::SameLine();
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::InputInt(CONCAT("##_spyserver_srv_port_", _this->name), &_this->port, 0, 0)) {
SmGui::SameLine();
SmGui::FillWidth();
if (SmGui::InputInt(CONCAT("##_spyserver_srv_port_", _this->name), &_this->port, 0, 0)) {
config.acquire();
config.conf["port"] = _this->port;
config.release(true);
}
if (connected) { style::endDisabled(); }
if (connected) { SmGui::EndDisabled(); }
if (_this->running) { style::beginDisabled(); }
if (!connected && ImGui::Button("Connect##spyserver_source", ImVec2(menuWidth, 0))) {
if (_this->running) { SmGui::BeginDisabled(); }
SmGui::FillWidth();
SmGui::ForceSync();
if (!connected && SmGui::Button("Connect##spyserver_source")) {
try {
if (_this->client) { _this->client.reset(); }
_this->client = spyserver::connect(_this->hostname, _this->port, &_this->stream);
@ -223,17 +225,17 @@ private:
spdlog::error("Could not connect to spyserver {0}", e.what());
}
}
else if (connected && ImGui::Button("Disconnect##spyserver_source", ImVec2(menuWidth, 0))) {
else if (connected && SmGui::Button("Disconnect##spyserver_source")) {
_this->client->close();
}
if (_this->running) { style::endDisabled(); }
if (_this->running) { SmGui::EndDisabled(); }
if (connected) {
if (_this->running) { style::beginDisabled(); }
ImGui::LeftLabel("Samplerate");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo("##spyserver_source_sr", &_this->srId, _this->sampleRatesTxt.c_str())) {
SmGui::LeftLabel("Samplerate");
SmGui::FillWidth();
if (SmGui::Combo("##spyserver_source_sr", &_this->srId, _this->sampleRatesTxt.c_str())) {
_this->sampleRate = _this->sampleRates[_this->srId];
core::setInputSampleRate(_this->sampleRate);
config.acquire();
@ -242,9 +244,9 @@ private:
}
if (_this->running) { style::endDisabled(); }
ImGui::LeftLabel("Sample bit depth");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo("##spyserver_source_type", &_this->iqType, streamFormatStr)) {
SmGui::LeftLabel("Sample bit depth");
SmGui::FillWidth();
if (SmGui::Combo("##spyserver_source_type", &_this->iqType, streamFormatStr)) {
int srvBits = streamFormatsBitCount[_this->iqType];
_this->client->setSetting(SPYSERVER_SETTING_IQ_FORMAT, streamFormats[_this->iqType]);
_this->client->setSetting(SPYSERVER_SETTING_IQ_DIGITAL_GAIN, _this->client->computeDigitalGain(srvBits, _this->gain, _this->srId + _this->client->devInfo.MinimumIQDecimation));
@ -255,8 +257,8 @@ private:
}
if (_this->client->devInfo.MaximumGainIndex) {
ImGui::SetNextItemWidth(menuWidth);
if (ImGui::SliderInt("##spyserver_source_gain", (int*)&_this->gain, 0, _this->client->devInfo.MaximumGainIndex)) {
SmGui::FillWidth();
if (SmGui::SliderInt("##spyserver_source_gain", (int*)&_this->gain, 0, _this->client->devInfo.MaximumGainIndex)) {
int srvBits = streamFormatsBitCount[_this->iqType];
_this->client->setSetting(SPYSERVER_SETTING_GAIN, _this->gain);
_this->client->setSetting(SPYSERVER_SETTING_IQ_DIGITAL_GAIN, _this->client->computeDigitalGain(srvBits, _this->gain, _this->srId + _this->client->devInfo.MinimumIQDecimation));
@ -266,14 +268,14 @@ private:
}
}
ImGui::Text("Status:");
ImGui::SameLine();
SmGui::Text("Status:");
SmGui::SameLine();
ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "Connected (%s)", deviceTypesStr[_this->client->devInfo.DeviceType]);
}
else {
ImGui::Text("Status:");
ImGui::SameLine();
ImGui::Text("Not connected");
SmGui::Text("Status:");
SmGui::SameLine();
SmGui::Text("Not connected");
}
}