mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-26 21:58:37 -05:00
Initial commit: Antenna support, Enhanced Settings menu, Enhanced SDR device dialog
This commit is contained in:
parent
e32e687fe8
commit
1042c62c3b
@ -39,6 +39,14 @@ long DeviceConfig::getSampleRate() {
|
|||||||
return sampleRate.load();
|
return sampleRate.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceConfig::setAntennaName(const std::string& name) {
|
||||||
|
antennaName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& DeviceConfig::getAntennaName() {
|
||||||
|
return antennaName;
|
||||||
|
}
|
||||||
|
|
||||||
void DeviceConfig::setAGCMode(bool agcMode) {
|
void DeviceConfig::setAGCMode(bool agcMode) {
|
||||||
this->agcMode.store(agcMode);
|
this->agcMode.store(agcMode);
|
||||||
}
|
}
|
||||||
@ -81,7 +89,9 @@ std::string DeviceConfig::getDeviceName() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DeviceConfig::save(DataNode *node) {
|
void DeviceConfig::save(DataNode *node) {
|
||||||
|
|
||||||
std::lock_guard < std::mutex > lock(busy_lock);
|
std::lock_guard < std::mutex > lock(busy_lock);
|
||||||
|
|
||||||
*node->newChild("id") = deviceId;
|
*node->newChild("id") = deviceId;
|
||||||
*node->newChild("name") = deviceName;
|
*node->newChild("name") = deviceName;
|
||||||
*node->newChild("ppm") = ppm.load();
|
*node->newChild("ppm") = ppm.load();
|
||||||
@ -89,6 +99,10 @@ void DeviceConfig::save(DataNode *node) {
|
|||||||
*node->newChild("sample_rate") = sampleRate.load();
|
*node->newChild("sample_rate") = sampleRate.load();
|
||||||
*node->newChild("agc_mode") = agcMode.load()?1:0;
|
*node->newChild("agc_mode") = agcMode.load()?1:0;
|
||||||
|
|
||||||
|
if (!antennaName.empty()) {
|
||||||
|
*node->newChild("antenna") = antennaName;
|
||||||
|
}
|
||||||
|
|
||||||
if (streamOpts.size()) {
|
if (streamOpts.size()) {
|
||||||
DataNode *streamOptsNode = node->newChild("streamOpts");
|
DataNode *streamOptsNode = node->newChild("streamOpts");
|
||||||
for (ConfigSettings::const_iterator opt_i = streamOpts.begin(); opt_i != streamOpts.end(); opt_i++) {
|
for (ConfigSettings::const_iterator opt_i = streamOpts.begin(); opt_i != streamOpts.end(); opt_i++) {
|
||||||
@ -149,6 +163,12 @@ void DeviceConfig::load(DataNode *node) {
|
|||||||
sample_rate_node->element()->get(sampleRateValue);
|
sample_rate_node->element()->get(sampleRateValue);
|
||||||
setSampleRate(sampleRateValue);
|
setSampleRate(sampleRateValue);
|
||||||
}
|
}
|
||||||
|
if (node->hasAnother("antenna")) {
|
||||||
|
DataNode *antenna_node = node->getNext("antenna");
|
||||||
|
std::string antennaNameValue;
|
||||||
|
antenna_node->element()->get(antennaNameValue);
|
||||||
|
setAntennaName(antennaNameValue);
|
||||||
|
}
|
||||||
if (node->hasAnother("streamOpts")) {
|
if (node->hasAnother("streamOpts")) {
|
||||||
DataNode *streamOptsNode = node->getNext("streamOpts");
|
DataNode *streamOptsNode = node->getNext("streamOpts");
|
||||||
for (int i = 0, iMax = streamOptsNode->numChildren(); i<iMax; i++) {
|
for (int i = 0, iMax = streamOptsNode->numChildren(); i<iMax; i++) {
|
||||||
|
@ -31,6 +31,9 @@ public:
|
|||||||
void setSampleRate(long srate);
|
void setSampleRate(long srate);
|
||||||
long getSampleRate();
|
long getSampleRate();
|
||||||
|
|
||||||
|
void setAntennaName(const std::string& name);
|
||||||
|
const std::string& getAntennaName();
|
||||||
|
|
||||||
void setAGCMode(bool agcMode);
|
void setAGCMode(bool agcMode);
|
||||||
bool getAGCMode();
|
bool getAGCMode();
|
||||||
|
|
||||||
@ -64,12 +67,14 @@ public:
|
|||||||
private:
|
private:
|
||||||
std::string deviceId;
|
std::string deviceId;
|
||||||
std::string deviceName;
|
std::string deviceName;
|
||||||
|
|
||||||
std::mutex busy_lock;
|
std::mutex busy_lock;
|
||||||
|
|
||||||
std::atomic_int ppm;
|
std::atomic_int ppm;
|
||||||
std::atomic_llong offset;
|
std::atomic_llong offset;
|
||||||
std::atomic_bool agcMode;
|
std::atomic_bool agcMode;
|
||||||
std::atomic_long sampleRate;
|
std::atomic_long sampleRate;
|
||||||
|
std::string antennaName;
|
||||||
ConfigSettings streamOpts;
|
ConfigSettings streamOpts;
|
||||||
ConfigGains gains;
|
ConfigGains gains;
|
||||||
std::map<std::string, std::string> settings;
|
std::map<std::string, std::string> settings;
|
||||||
|
@ -752,11 +752,13 @@ void AppFrame::updateDeviceParams() {
|
|||||||
|
|
||||||
newSettingsMenu->AppendSeparator();
|
newSettingsMenu->AppendSeparator();
|
||||||
|
|
||||||
newSettingsMenu->Append(wxID_SET_DB_OFFSET, "Power Level Offset");
|
settingsMenuItems.clear();
|
||||||
newSettingsMenu->Append(wxID_SET_FREQ_OFFSET, "Frequency Offset");
|
|
||||||
|
settingsMenuItems[wxID_SET_DB_OFFSET] = newSettingsMenu->Append(wxID_SET_DB_OFFSET, wxT("Power Level Offset : ") + std::to_string(wxGetApp().getConfig()->getDBOffset()) + wxT(" dB"));
|
||||||
|
settingsMenuItems[wxID_SET_FREQ_OFFSET] = newSettingsMenu->Append(wxID_SET_FREQ_OFFSET, wxT("Frequency Offset : ") + std::to_string(wxGetApp().getOffset()) + wxT(" Hz"));
|
||||||
|
|
||||||
if (devInfo->hasCORR(SOAPY_SDR_RX, 0)) {
|
if (devInfo->hasCORR(SOAPY_SDR_RX, 0)) {
|
||||||
newSettingsMenu->Append(wxID_SET_PPM, "Device PPM");
|
settingsMenuItems[wxID_SET_PPM] = newSettingsMenu->Append(wxID_SET_PPM, wxT("Device PPM : ") + std::to_string(wxGetApp().getPPM()) + wxT(" ppm"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (devInfo->getDriver() != "rtlsdr") {
|
if (devInfo->getDriver() != "rtlsdr") {
|
||||||
@ -771,7 +773,43 @@ void AppFrame::updateDeviceParams() {
|
|||||||
} else if (!wxGetApp().getAGCMode()) {
|
} else if (!wxGetApp().getAGCMode()) {
|
||||||
wxGetApp().setAGCMode(true);
|
wxGetApp().setAGCMode(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Add an Antenna menu if more than one (RX) antenna, to keep the UI free of useless entries
|
||||||
|
antennaNames.clear();
|
||||||
|
antennaMenuItems.clear();
|
||||||
|
std::vector<std::string> availableAntennas = devInfo->getAntennaNames(SOAPY_SDR_RX, 0);
|
||||||
|
|
||||||
|
if (availableAntennas.size() > 1) {
|
||||||
|
|
||||||
|
newSettingsMenu->AppendSeparator();
|
||||||
|
|
||||||
|
antennaNames = availableAntennas;
|
||||||
|
|
||||||
|
wxMenu *subMenu = new wxMenu;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
std::string antennaChecked;
|
||||||
|
for (std::string currentAntenna : availableAntennas) {
|
||||||
|
|
||||||
|
antennaMenuItems[wxID_ANTENNAS_BASE + i] = subMenu->AppendRadioItem(wxID_ANTENNAS_BASE + i, currentAntenna);
|
||||||
|
|
||||||
|
if (wxGetApp().getAntennaName() == currentAntenna) {
|
||||||
|
antennaMenuItems[wxID_ANTENNAS_BASE + i]->Check(true);
|
||||||
|
antennaChecked = currentAntenna;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
antennaMenuItems[wxID_ANTENNA_CURRENT] = newSettingsMenu->AppendSubMenu(subMenu, "Antenna");
|
||||||
|
|
||||||
|
//Change the Antenna label to indicate the current antenna.
|
||||||
|
if (!antennaChecked.empty()) {
|
||||||
|
antennaMenuItems[wxID_ANTENNA_CURRENT]->SetItemLabel(wxT("Antenna : ") + antennaChecked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Runtime settings part
|
||||||
|
|
||||||
SoapySDR::ArgInfoList::const_iterator args_i;
|
SoapySDR::ArgInfoList::const_iterator args_i;
|
||||||
settingArgs = soapyDev->getSettingInfo();
|
settingArgs = soapyDev->getSettingInfo();
|
||||||
|
|
||||||
@ -790,15 +828,17 @@ void AppFrame::updateDeviceParams() {
|
|||||||
item->Check(currentVal=="true");
|
item->Check(currentVal=="true");
|
||||||
i++;
|
i++;
|
||||||
} else if (arg.type == SoapySDR::ArgInfo::INT) {
|
} else if (arg.type == SoapySDR::ArgInfo::INT) {
|
||||||
newSettingsMenu->Append(wxID_SETTINGS_BASE+i, arg.name, arg.description);
|
|
||||||
|
settingsMenuItems[wxID_SETTINGS_BASE + i] = newSettingsMenu->Append(wxID_SETTINGS_BASE + i, wxString(arg.name) + " : " + currentVal, arg.description);
|
||||||
i++;
|
i++;
|
||||||
} else if (arg.type == SoapySDR::ArgInfo::FLOAT) {
|
} else if (arg.type == SoapySDR::ArgInfo::FLOAT) {
|
||||||
newSettingsMenu->Append(wxID_SETTINGS_BASE+i, arg.name, arg.description);
|
settingsMenuItems[wxID_SETTINGS_BASE + i] = newSettingsMenu->Append(wxID_SETTINGS_BASE + i, wxString(arg.name) + " : " + currentVal, arg.description);
|
||||||
i++;
|
i++;
|
||||||
} else if (arg.type == SoapySDR::ArgInfo::STRING) {
|
} else if (arg.type == SoapySDR::ArgInfo::STRING) {
|
||||||
if (arg.options.size()) {
|
if (arg.options.size()) {
|
||||||
wxMenu *subMenu = new wxMenu;
|
wxMenu *subMenu = new wxMenu;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
std::vector<int> subItemsIds;
|
||||||
//for each of this options
|
//for each of this options
|
||||||
for (std::string optName : arg.options) {
|
for (std::string optName : arg.options) {
|
||||||
//by default the option name is the same as the displayed name.
|
//by default the option name is the same as the displayed name.
|
||||||
@ -808,15 +848,21 @@ void AppFrame::updateDeviceParams() {
|
|||||||
displayName = arg.optionNames[j];
|
displayName = arg.optionNames[j];
|
||||||
}
|
}
|
||||||
wxMenuItem *item = subMenu->AppendRadioItem(wxID_SETTINGS_BASE+i, displayName);
|
wxMenuItem *item = subMenu->AppendRadioItem(wxID_SETTINGS_BASE+i, displayName);
|
||||||
|
subItemsIds.push_back(wxID_SETTINGS_BASE + i);
|
||||||
|
|
||||||
if (currentVal == optName) {
|
if (currentVal == optName) {
|
||||||
item->Check(true);
|
item->Check(true);
|
||||||
}
|
}
|
||||||
j++;
|
j++;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
newSettingsMenu->AppendSubMenu(subMenu, arg.name, arg.description);
|
settingsMenuItems[wxID_SETTINGS_BASE + i] = newSettingsMenu->AppendSubMenu(subMenu, wxString(arg.name) + " : " + currentVal, arg.description);
|
||||||
|
//map subitems ids to their parent item !
|
||||||
|
for (int currentSubId : subItemsIds) {
|
||||||
|
settingsMenuItems[currentSubId] = settingsMenuItems[wxID_SETTINGS_BASE + i];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
newSettingsMenu->Append(wxID_SETTINGS_BASE+i, arg.name, arg.description);
|
settingsMenuItems[wxID_SETTINGS_BASE + i] = newSettingsMenu->Append(wxID_SETTINGS_BASE + i, wxString(arg.name) + " : " + currentVal, arg.description);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1104,7 +1150,14 @@ bool AppFrame::actionOnMenuAbout(wxCommandEvent& event) {
|
|||||||
|
|
||||||
bool AppFrame::actionOnMenuSettings(wxCommandEvent& event) {
|
bool AppFrame::actionOnMenuSettings(wxCommandEvent& event) {
|
||||||
|
|
||||||
if (event.GetId() >= wxID_SETTINGS_BASE && event.GetId() < settingsIdMax) {
|
if (event.GetId() >= wxID_ANTENNAS_BASE && event.GetId() < wxID_ANTENNAS_BASE + antennaNames.size()) {
|
||||||
|
|
||||||
|
wxGetApp().setAntennaName(antennaNames[event.GetId() - wxID_ANTENNAS_BASE]);
|
||||||
|
|
||||||
|
antennaMenuItems[wxID_ANTENNA_CURRENT]->SetItemLabel(wxT("Antenna : ") + wxGetApp().getAntennaName());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (event.GetId() >= wxID_SETTINGS_BASE && event.GetId() < settingsIdMax) {
|
||||||
|
|
||||||
int setIdx = event.GetId() - wxID_SETTINGS_BASE;
|
int setIdx = event.GetId() - wxID_SETTINGS_BASE;
|
||||||
int menuIdx = 0;
|
int menuIdx = 0;
|
||||||
@ -1115,6 +1168,9 @@ bool AppFrame::actionOnMenuSettings(wxCommandEvent& event) {
|
|||||||
if (arg.type == SoapySDR::ArgInfo::STRING && arg.options.size() && setIdx >= menuIdx && setIdx < menuIdx + (int)arg.options.size()) {
|
if (arg.type == SoapySDR::ArgInfo::STRING && arg.options.size() && setIdx >= menuIdx && setIdx < menuIdx + (int)arg.options.size()) {
|
||||||
int optIdx = setIdx - menuIdx;
|
int optIdx = setIdx - menuIdx;
|
||||||
wxGetApp().getSDRThread()->writeSetting(arg.key, arg.options[optIdx]);
|
wxGetApp().getSDRThread()->writeSetting(arg.key, arg.options[optIdx]);
|
||||||
|
//update parent menu item label to display the current value
|
||||||
|
settingsMenuItems[menuIdx + wxID_SETTINGS_BASE]->SetItemLabel(wxString(arg.name) + " : " + arg.options[optIdx]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (arg.type == SoapySDR::ArgInfo::STRING && arg.options.size()) {
|
else if (arg.type == SoapySDR::ArgInfo::STRING && arg.options.size()) {
|
||||||
@ -1127,6 +1183,9 @@ bool AppFrame::actionOnMenuSettings(wxCommandEvent& event) {
|
|||||||
}
|
}
|
||||||
else if (arg.type == SoapySDR::ArgInfo::STRING) {
|
else if (arg.type == SoapySDR::ArgInfo::STRING) {
|
||||||
wxString stringVal = wxGetTextFromUser(arg.description, arg.name, wxGetApp().getSDRThread()->readSetting(arg.key));
|
wxString stringVal = wxGetTextFromUser(arg.description, arg.name, wxGetApp().getSDRThread()->readSetting(arg.key));
|
||||||
|
|
||||||
|
settingsMenuItems[menuIdx + wxID_SETTINGS_BASE]->SetItemLabel(wxString(arg.name) + " : " + stringVal);
|
||||||
|
|
||||||
if (stringVal.ToStdString() != "") {
|
if (stringVal.ToStdString() != "") {
|
||||||
wxGetApp().getSDRThread()->writeSetting(arg.key, stringVal.ToStdString());
|
wxGetApp().getSDRThread()->writeSetting(arg.key, stringVal.ToStdString());
|
||||||
}
|
}
|
||||||
@ -1141,6 +1200,9 @@ bool AppFrame::actionOnMenuSettings(wxCommandEvent& event) {
|
|||||||
currentVal = 0;
|
currentVal = 0;
|
||||||
}
|
}
|
||||||
int intVal = wxGetNumberFromUser(arg.description, arg.units, arg.name, currentVal, arg.range.minimum(), arg.range.maximum(), this);
|
int intVal = wxGetNumberFromUser(arg.description, arg.units, arg.name, currentVal, arg.range.minimum(), arg.range.maximum(), this);
|
||||||
|
|
||||||
|
settingsMenuItems[menuIdx + wxID_SETTINGS_BASE]->SetItemLabel(wxString(arg.name) + " : " + std::to_string(intVal));
|
||||||
|
|
||||||
if (intVal != -1) {
|
if (intVal != -1) {
|
||||||
wxGetApp().getSDRThread()->writeSetting(arg.key, std::to_string(intVal));
|
wxGetApp().getSDRThread()->writeSetting(arg.key, std::to_string(intVal));
|
||||||
}
|
}
|
||||||
@ -1154,6 +1216,7 @@ bool AppFrame::actionOnMenuSettings(wxCommandEvent& event) {
|
|||||||
catch (std::invalid_argument e) {
|
catch (std::invalid_argument e) {
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
settingsMenuItems[menuIdx + wxID_SETTINGS_BASE]->SetItemLabel(wxString(arg.name) + " : " + floatVal);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1508,6 +1571,8 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
|||||||
"Frequency Offset", wxGetApp().getOffset(), -2000000000, 2000000000, this);
|
"Frequency Offset", wxGetApp().getOffset(), -2000000000, 2000000000, this);
|
||||||
if (ofs != -1) {
|
if (ofs != -1) {
|
||||||
wxGetApp().setOffset(ofs);
|
wxGetApp().setOffset(ofs);
|
||||||
|
|
||||||
|
settingsMenuItems[wxID_SET_FREQ_OFFSET]->SetItemLabel(wxT("Frequency Offset : ") + std::to_string(wxGetApp().getOffset()) + wxT(" Hz"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (event.GetId() == wxID_SET_DB_OFFSET) {
|
else if (event.GetId() == wxID_SET_DB_OFFSET) {
|
||||||
@ -1515,6 +1580,7 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
|||||||
"Power Level Offset", wxGetApp().getConfig()->getDBOffset(), -1000, 1000, this);
|
"Power Level Offset", wxGetApp().getConfig()->getDBOffset(), -1000, 1000, this);
|
||||||
if (ofs != -1) {
|
if (ofs != -1) {
|
||||||
wxGetApp().getConfig()->setDBOffset(ofs);
|
wxGetApp().getConfig()->setDBOffset(ofs);
|
||||||
|
settingsMenuItems[wxID_SET_DB_OFFSET]->SetItemLabel(wxT("Power Level Offset : ") + std::to_string(wxGetApp().getConfig()->getDBOffset()) + wxT(" dB"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (actionOnMenuAGC(event)) {
|
else if (actionOnMenuAGC(event)) {
|
||||||
@ -1527,6 +1593,8 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
|||||||
long ofs = wxGetNumberFromUser("Frequency correction for device in PPM.\ni.e. -51 for -51 PPM\n\nNote: you can adjust PPM interactively\nby holding ALT over the frequency tuning bar.\n", "Parts per million (PPM)",
|
long ofs = wxGetNumberFromUser("Frequency correction for device in PPM.\ni.e. -51 for -51 PPM\n\nNote: you can adjust PPM interactively\nby holding ALT over the frequency tuning bar.\n", "Parts per million (PPM)",
|
||||||
"Frequency Correction", wxGetApp().getPPM(), -1000, 1000, this);
|
"Frequency Correction", wxGetApp().getPPM(), -1000, 1000, this);
|
||||||
wxGetApp().setPPM(ofs);
|
wxGetApp().setPPM(ofs);
|
||||||
|
|
||||||
|
settingsMenuItems[wxID_SET_PPM]->SetItemLabel(wxT("Device PPM : ") + std::to_string(wxGetApp().getPPM()) + wxT(" ppm"));
|
||||||
}
|
}
|
||||||
else if (actionOnMenuLoadSave(event)) {
|
else if (actionOnMenuLoadSave(event)) {
|
||||||
return;
|
return;
|
||||||
@ -2019,13 +2087,14 @@ void AppFrame::OnAboutDialogClose(wxCommandEvent& event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AppFrame::saveSession(std::string fileName) {
|
void AppFrame::saveSession(std::string fileName) {
|
||||||
|
|
||||||
DataTree s("cubicsdr_session");
|
DataTree s("cubicsdr_session");
|
||||||
DataNode *header = s.rootNode()->newChild("header");
|
DataNode *header = s.rootNode()->newChild("header");
|
||||||
//save as wstring to prevent problems
|
//save as wstring to prevent problems
|
||||||
header->newChild("version")->element()->set(wxString(CUBICSDR_VERSION).ToStdWstring());
|
header->newChild("version")->element()->set(wxString(CUBICSDR_VERSION).ToStdWstring());
|
||||||
|
|
||||||
*header->newChild("center_freq") = wxGetApp().getFrequency();
|
*header->newChild("center_freq") = wxGetApp().getFrequency();
|
||||||
*header->newChild("sample_rate") = wxGetApp().getSampleRate();
|
*header->newChild("sample_rate") = wxGetApp().getSampleRate();
|
||||||
*header->newChild("solo_mode") = wxGetApp().getSoloMode()?1:0;
|
*header->newChild("solo_mode") = wxGetApp().getSoloMode()?1:0;
|
||||||
|
|
||||||
if (waterfallCanvas->getViewState()) {
|
if (waterfallCanvas->getViewState()) {
|
||||||
@ -2061,6 +2130,7 @@ void AppFrame::saveSession(std::string fileName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool AppFrame::loadSession(std::string fileName) {
|
bool AppFrame::loadSession(std::string fileName) {
|
||||||
|
|
||||||
DataTree l;
|
DataTree l;
|
||||||
if (!l.LoadFromFileXML(fileName)) {
|
if (!l.LoadFromFileXML(fileName)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -64,6 +64,9 @@
|
|||||||
|
|
||||||
#define wxID_SETTINGS_BASE 2300
|
#define wxID_SETTINGS_BASE 2300
|
||||||
|
|
||||||
|
#define wxID_ANTENNA_CURRENT 2500
|
||||||
|
#define wxID_ANTENNAS_BASE 2501
|
||||||
|
|
||||||
#define wxID_DEVICE_ID 3500
|
#define wxID_DEVICE_ID 3500
|
||||||
|
|
||||||
#define wxID_AUDIO_BANDWIDTH_BASE 9000
|
#define wxID_AUDIO_BANDWIDTH_BASE 9000
|
||||||
@ -192,6 +195,12 @@ private:
|
|||||||
std::map<int,RtAudio::DeviceInfo> outputDevices;
|
std::map<int,RtAudio::DeviceInfo> outputDevices;
|
||||||
std::map<int, wxMenuItem *> outputDeviceMenuItems;
|
std::map<int, wxMenuItem *> outputDeviceMenuItems;
|
||||||
std::map<int, wxMenuItem *> sampleRateMenuItems;
|
std::map<int, wxMenuItem *> sampleRateMenuItems;
|
||||||
|
std::map<int, wxMenuItem *> antennaMenuItems;
|
||||||
|
|
||||||
|
//depending on context, maps the item id to wxMenuItem*,
|
||||||
|
//OR the submenu item id to its parent wxMenuItem*.
|
||||||
|
std::map<int, wxMenuItem *> settingsMenuItems;
|
||||||
|
|
||||||
std::map<int, wxMenuItem *> audioSampleRateMenuItems;
|
std::map<int, wxMenuItem *> audioSampleRateMenuItems;
|
||||||
std::map<int, wxMenuItem *> directSamplingMenuItems;
|
std::map<int, wxMenuItem *> directSamplingMenuItems;
|
||||||
wxMenuBar *menuBar;
|
wxMenuBar *menuBar;
|
||||||
@ -207,6 +216,8 @@ private:
|
|||||||
int settingsIdMax;
|
int settingsIdMax;
|
||||||
std::vector<long> sampleRates;
|
std::vector<long> sampleRates;
|
||||||
long manualSampleRate = -1;
|
long manualSampleRate = -1;
|
||||||
|
|
||||||
|
std::vector<std::string> antennaNames;
|
||||||
|
|
||||||
std::string currentSessionFile;
|
std::string currentSessionFile;
|
||||||
|
|
||||||
|
@ -629,9 +629,22 @@ long long CubicSDR::getOffset() {
|
|||||||
|
|
||||||
void CubicSDR::setOffset(long long ofs) {
|
void CubicSDR::setOffset(long long ofs) {
|
||||||
offset = ofs;
|
offset = ofs;
|
||||||
sdrThread->setOffset(offset);
|
|
||||||
SDRDeviceInfo *dev = getDevice();
|
if (sdrThread && !sdrThread->isTerminated()) {
|
||||||
config.getDevice(dev->getDeviceId())->setOffset(ofs);
|
sdrThread->setOffset(offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CubicSDR::setAntennaName(const std::string& name) {
|
||||||
|
antennaName = name;
|
||||||
|
|
||||||
|
if (sdrThread && !sdrThread->isTerminated()) {
|
||||||
|
sdrThread->setAntenna(antennaName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& CubicSDR::getAntennaName() {
|
||||||
|
return antennaName;
|
||||||
}
|
}
|
||||||
|
|
||||||
long long CubicSDR::getFrequency() {
|
long long CubicSDR::getFrequency() {
|
||||||
@ -654,12 +667,18 @@ bool CubicSDR::isFrequencyLocked() {
|
|||||||
|
|
||||||
void CubicSDR::unlockFrequency() {
|
void CubicSDR::unlockFrequency() {
|
||||||
frequency_locked.store(false);
|
frequency_locked.store(false);
|
||||||
sdrThread->unlockFrequency();
|
if (sdrThread && !sdrThread->isTerminated()) {
|
||||||
|
sdrThread->unlockFrequency();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubicSDR::setSampleRate(long long rate_in) {
|
void CubicSDR::setSampleRate(long long rate_in) {
|
||||||
sampleRate = rate_in;
|
sampleRate = rate_in;
|
||||||
sdrThread->setSampleRate(sampleRate);
|
|
||||||
|
if (sdrThread && !sdrThread->isTerminated()) {
|
||||||
|
sdrThread->setSampleRate(sampleRate);
|
||||||
|
}
|
||||||
|
|
||||||
setFrequency(frequency);
|
setFrequency(frequency);
|
||||||
|
|
||||||
if (rate_in <= CHANNELIZER_RATE_MAX / 8) {
|
if (rate_in <= CHANNELIZER_RATE_MAX / 8) {
|
||||||
@ -750,13 +769,8 @@ void CubicSDR::setDevice(SDRDeviceInfo *dev, int waitMsForTermination) {
|
|||||||
|
|
||||||
setPPM(devConfig->getPPM());
|
setPPM(devConfig->getPPM());
|
||||||
setOffset(devConfig->getOffset());
|
setOffset(devConfig->getOffset());
|
||||||
|
setAGCMode(devConfig->getAGCMode());
|
||||||
|
setAntennaName(devConfig->getAntennaName());
|
||||||
if (devConfig->getAGCMode()) {
|
|
||||||
setAGCMode(true);
|
|
||||||
} else {
|
|
||||||
setAGCMode(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
t_SDR = new std::thread(&SDRThread::threadMain, sdrThread);
|
t_SDR = new std::thread(&SDRThread::threadMain, sdrThread);
|
||||||
}
|
}
|
||||||
@ -859,11 +873,8 @@ void CubicSDR::saveConfig() {
|
|||||||
|
|
||||||
void CubicSDR::setPPM(int ppm_in) {
|
void CubicSDR::setPPM(int ppm_in) {
|
||||||
ppm = ppm_in;
|
ppm = ppm_in;
|
||||||
sdrThread->setPPM(ppm);
|
if (sdrThread && !sdrThread->isTerminated()) {
|
||||||
|
sdrThread->setPPM(ppm);
|
||||||
SDRDeviceInfo *dev = getDevice();
|
|
||||||
if (dev) {
|
|
||||||
config.getDevice(dev->getDeviceId())->setPPM(ppm_in);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -975,7 +986,10 @@ bool CubicSDR::isDeviceSelectorOpen() {
|
|||||||
|
|
||||||
void CubicSDR::setAGCMode(bool mode) {
|
void CubicSDR::setAGCMode(bool mode) {
|
||||||
agcMode.store(mode);
|
agcMode.store(mode);
|
||||||
sdrThread->setAGCMode(mode);
|
|
||||||
|
if (sdrThread && !sdrThread->isTerminated()) {
|
||||||
|
sdrThread->setAGCMode(mode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CubicSDR::getAGCMode() {
|
bool CubicSDR::getAGCMode() {
|
||||||
|
@ -91,6 +91,9 @@ public:
|
|||||||
|
|
||||||
void setOffset(long long ofs);
|
void setOffset(long long ofs);
|
||||||
long long getOffset();
|
long long getOffset();
|
||||||
|
|
||||||
|
void setAntennaName(const std::string& name);
|
||||||
|
const std::string& getAntennaName();
|
||||||
|
|
||||||
void setDBOffset(int ofs);
|
void setDBOffset(int ofs);
|
||||||
int getDBOffset();
|
int getDBOffset();
|
||||||
@ -98,6 +101,7 @@ public:
|
|||||||
void setSampleRate(long long rate_in);
|
void setSampleRate(long long rate_in);
|
||||||
long long getSampleRate();
|
long long getSampleRate();
|
||||||
|
|
||||||
|
|
||||||
std::vector<SDRDeviceInfo *> *getDevices();
|
std::vector<SDRDeviceInfo *> *getDevices();
|
||||||
void setDevice(SDRDeviceInfo *dev, int waitMsForTermination);
|
void setDevice(SDRDeviceInfo *dev, int waitMsForTermination);
|
||||||
void stopDevice(bool store, int waitMsForTermination);
|
void stopDevice(bool store, int waitMsForTermination);
|
||||||
@ -189,6 +193,7 @@ private:
|
|||||||
std::atomic_llong offset;
|
std::atomic_llong offset;
|
||||||
std::atomic_int ppm, snap;
|
std::atomic_int ppm, snap;
|
||||||
std::atomic_llong sampleRate;
|
std::atomic_llong sampleRate;
|
||||||
|
std::string antennaName;
|
||||||
std::atomic_bool agcMode;
|
std::atomic_bool agcMode;
|
||||||
|
|
||||||
SDRThread *sdrThread = nullptr;
|
SDRThread *sdrThread = nullptr;
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include "CubicSDR.h"
|
#include "CubicSDR.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include "CubicSDR.xpm"
|
#include "CubicSDR.xpm"
|
||||||
#endif
|
#endif
|
||||||
@ -110,6 +112,7 @@ wxPGProperty *SDRDevicesDialog::addArgInfoProperty(wxPropertyGrid *pg, SoapySDR:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SDRDevicesDialog::refreshDeviceProperties() {
|
void SDRDevicesDialog::refreshDeviceProperties() {
|
||||||
|
|
||||||
SDRDeviceInfo *selDev = getSelectedDevice(devTree->GetSelection());
|
SDRDeviceInfo *selDev = getSelectedDevice(devTree->GetSelection());
|
||||||
if (selDev && selDev->isAvailable()) {
|
if (selDev && selDev->isAvailable()) {
|
||||||
dev = selDev;
|
dev = selDev;
|
||||||
@ -120,13 +123,68 @@ void SDRDevicesDialog::refreshDeviceProperties() {
|
|||||||
SoapySDR::Device *soapyDev = dev->getSoapyDevice();
|
SoapySDR::Device *soapyDev = dev->getSoapyDevice();
|
||||||
SoapySDR::ArgInfoList args = soapyDev->getSettingInfo();
|
SoapySDR::ArgInfoList args = soapyDev->getSettingInfo();
|
||||||
|
|
||||||
|
//A) General settings: name, offset, sample rate, agc, antennas (if > 1)
|
||||||
m_propertyGrid->Append(new wxPropertyCategory("General Settings"));
|
m_propertyGrid->Append(new wxPropertyCategory("General Settings"));
|
||||||
|
|
||||||
devSettings.clear();
|
devSettings.clear();
|
||||||
|
|
||||||
|
//A-1) Name
|
||||||
devSettings["name"] = m_propertyGrid->Append( new wxStringProperty("Name", wxPG_LABEL, devConfig->getDeviceName()) );
|
devSettings["name"] = m_propertyGrid->Append( new wxStringProperty("Name", wxPG_LABEL, devConfig->getDeviceName()) );
|
||||||
|
//A-2) Offset
|
||||||
devSettings["offset"] = m_propertyGrid->Append( new wxIntProperty("Offset (Hz)", wxPG_LABEL, devConfig->getOffset()) );
|
devSettings["offset"] = m_propertyGrid->Append( new wxIntProperty("Offset (Hz)", wxPG_LABEL, devConfig->getOffset()) );
|
||||||
|
//A-3) ppm
|
||||||
|
devSettings["ppm"] = m_propertyGrid->Append(new wxIntProperty("Frequency Correction (ppm)", wxPG_LABEL, devConfig->getPPM()));
|
||||||
|
|
||||||
|
|
||||||
|
//A-4) AGC control
|
||||||
|
SoapySDR::ArgInfo agcArg;
|
||||||
|
|
||||||
|
agcArg.type = SoapySDR::ArgInfo::BOOL;
|
||||||
|
agcArg.units = "";
|
||||||
|
agcArg.name = "Automatic Gain";
|
||||||
|
agcArg.key = "agc_mode";
|
||||||
|
agcArg.value = devConfig->getAGCMode()?"true":"false"; //must be lowercase for addArgInfoProperty
|
||||||
|
|
||||||
|
devSettings["agc_mode"] = addArgInfoProperty(m_propertyGrid, agcArg);
|
||||||
|
|
||||||
|
//A-5) Antennas, is there are more than 1 RX antenna, else do not expose the setting.
|
||||||
|
//get the saved setting
|
||||||
|
const std::string& currentSetAntenna = wxGetApp().getAntennaName();
|
||||||
|
|
||||||
|
//compare to the list of existing antennas
|
||||||
|
SoapySDR::ArgInfo antennasArg;
|
||||||
|
std::vector<std::string> antennaOpts = selDev->getAntennaNames(SOAPY_SDR_RX, 0);
|
||||||
|
|
||||||
|
//only do something if there is more than 1 antenna
|
||||||
|
if (antennaOpts.size() > 1) {
|
||||||
|
|
||||||
|
//by default, choose the first of the list.
|
||||||
|
std::string antennaToSelect = antennaOpts.front();
|
||||||
|
|
||||||
|
auto found_i = std::find(antennaOpts.begin(), antennaOpts.end(), currentSetAntenna);
|
||||||
|
|
||||||
|
if (found_i != antennaOpts.end()) {
|
||||||
|
antennaToSelect = currentSetAntenna;
|
||||||
|
}
|
||||||
|
|
||||||
|
//build device settings
|
||||||
|
for (std::string antenna : antennaOpts) {
|
||||||
|
antennasArg.options.push_back(antenna);
|
||||||
|
antennasArg.optionNames.push_back(antenna);
|
||||||
|
}
|
||||||
|
|
||||||
|
antennasArg.type = SoapySDR::ArgInfo::STRING;
|
||||||
|
antennasArg.units = "";
|
||||||
|
antennasArg.name = "Antenna";
|
||||||
|
antennasArg.key = "antenna";
|
||||||
|
antennasArg.value = antennaToSelect;
|
||||||
|
|
||||||
|
devSettings["antenna"] = addArgInfoProperty(m_propertyGrid, antennasArg);
|
||||||
|
deviceArgs["antenna"] = antennasArg;
|
||||||
|
|
||||||
|
} //end if more than 1 antenna
|
||||||
|
|
||||||
|
//A-6) Sample_rate:
|
||||||
long currentSampleRate = wxGetApp().getSampleRate();
|
long currentSampleRate = wxGetApp().getSampleRate();
|
||||||
long deviceSampleRate = devConfig->getSampleRate();
|
long deviceSampleRate = devConfig->getSampleRate();
|
||||||
|
|
||||||
@ -150,11 +208,14 @@ void SDRDevicesDialog::refreshDeviceProperties() {
|
|||||||
|
|
||||||
devSettings["sample_rate"] = addArgInfoProperty(m_propertyGrid, sampleRateArg);
|
devSettings["sample_rate"] = addArgInfoProperty(m_propertyGrid, sampleRateArg);
|
||||||
deviceArgs["sample_rate"] = sampleRateArg;
|
deviceArgs["sample_rate"] = sampleRateArg;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//B) Runtime Settings:
|
||||||
runtimeArgs.clear();
|
runtimeArgs.clear();
|
||||||
runtimeProps.clear();
|
runtimeProps.clear();
|
||||||
streamProps.clear();
|
streamProps.clear();
|
||||||
|
|
||||||
if (args.size()) {
|
if (args.size()) {
|
||||||
m_propertyGrid->Append(new wxPropertyCategory("Run-time Settings"));
|
m_propertyGrid->Append(new wxPropertyCategory("Run-time Settings"));
|
||||||
|
|
||||||
@ -439,6 +500,7 @@ void SDRDevicesDialog::OnRefreshDevices( wxMouseEvent& /* event */) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SDRDevicesDialog::OnPropGridChanged( wxPropertyGridEvent& event ) {
|
void SDRDevicesDialog::OnPropGridChanged( wxPropertyGridEvent& event ) {
|
||||||
|
|
||||||
if (editId && event.GetProperty() == devSettings["name"]) {
|
if (editId && event.GetProperty() == devSettings["name"]) {
|
||||||
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId());
|
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId());
|
||||||
|
|
||||||
@ -457,7 +519,36 @@ void SDRDevicesDialog::OnPropGridChanged( wxPropertyGridEvent& event ) {
|
|||||||
long offset = event.GetPropertyValue().GetInteger();
|
long offset = event.GetPropertyValue().GetInteger();
|
||||||
|
|
||||||
devConfig->setOffset(offset);
|
devConfig->setOffset(offset);
|
||||||
|
if (dev->isActive() || !wxGetApp().getDevice()) {
|
||||||
|
|
||||||
|
wxGetApp().setOffset(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (dev && event.GetProperty() == devSettings["ppm"]) {
|
||||||
|
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId());
|
||||||
|
|
||||||
|
int ppm = event.GetPropertyValue().GetInteger();
|
||||||
|
|
||||||
|
devConfig->setPPM(ppm);
|
||||||
|
|
||||||
|
if (dev->isActive() || !wxGetApp().getDevice()) {
|
||||||
|
|
||||||
|
wxGetApp().setPPM(ppm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dev && event.GetProperty() == devSettings["agc_mode"]) {
|
||||||
|
|
||||||
|
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId());
|
||||||
|
|
||||||
|
bool agcMode = event.GetPropertyValue().GetBool();
|
||||||
|
|
||||||
|
devConfig->setAGCMode(agcMode);
|
||||||
|
if (dev->isActive() || !wxGetApp().getDevice()) {
|
||||||
|
wxGetApp().setAGCMode(agcMode);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (dev && event.GetProperty() == devSettings["sample_rate"]) {
|
} else if (dev && event.GetProperty() == devSettings["sample_rate"]) {
|
||||||
|
|
||||||
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId());
|
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId());
|
||||||
|
|
||||||
std::string strRate = deviceArgs["sample_rate"].options[event.GetPropertyValue().GetInteger()];
|
std::string strRate = deviceArgs["sample_rate"].options[event.GetPropertyValue().GetInteger()];
|
||||||
@ -465,15 +556,29 @@ void SDRDevicesDialog::OnPropGridChanged( wxPropertyGridEvent& event ) {
|
|||||||
try {
|
try {
|
||||||
srate = std::stol(strRate);
|
srate = std::stol(strRate);
|
||||||
devConfig->setSampleRate(srate);
|
devConfig->setSampleRate(srate);
|
||||||
|
if (dev->isActive() || !wxGetApp().getDevice()) {
|
||||||
if (dev->isActive() || !wxGetApp().getDevice()) {
|
|
||||||
wxGetApp().setSampleRate(srate);
|
wxGetApp().setSampleRate(srate);
|
||||||
wxGetApp().notifyMainUIOfDeviceChange();
|
}
|
||||||
}
|
|
||||||
} catch (std::invalid_argument e) {
|
} catch (std::invalid_argument e) {
|
||||||
// nop
|
// nop
|
||||||
}
|
}
|
||||||
} else if (editId && dev) {
|
} else if (dev && event.GetProperty() == devSettings["antenna"]) {
|
||||||
|
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId());
|
||||||
|
|
||||||
|
std::string strAntennaName = deviceArgs["antenna"].options[event.GetPropertyValue().GetInteger()];
|
||||||
|
|
||||||
|
try {
|
||||||
|
devConfig->setAntennaName(strAntennaName);
|
||||||
|
|
||||||
|
if (dev->isActive() || !wxGetApp().getDevice()) {
|
||||||
|
wxGetApp().setAntennaName(strAntennaName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::invalid_argument e) {
|
||||||
|
// nop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (editId && dev) {
|
||||||
wxPGProperty *prop = event.GetProperty();
|
wxPGProperty *prop = event.GetProperty();
|
||||||
//change value of RuntimeProps
|
//change value of RuntimeProps
|
||||||
for (std::map<std::string, wxPGProperty *>::iterator rtp = runtimeProps.begin(); rtp != runtimeProps.end(); rtp++) {
|
for (std::map<std::string, wxPGProperty *>::iterator rtp = runtimeProps.begin(); rtp != runtimeProps.end(); rtp++) {
|
||||||
@ -499,6 +604,8 @@ void SDRDevicesDialog::OnPropGridChanged( wxPropertyGridEvent& event ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// general refresh.
|
||||||
|
wxGetApp().notifyMainUIOfDeviceChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDRDevicesDialog::OnPropGridFocus( wxFocusEvent& /* event */) {
|
void SDRDevicesDialog::OnPropGridFocus( wxFocusEvent& /* event */) {
|
||||||
|
@ -190,6 +190,13 @@ std::vector<long> SDRDeviceInfo::getSampleRates(int direction, size_t channel) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> SDRDeviceInfo::getAntennaNames(int direction, size_t channel) {
|
||||||
|
SoapySDR::Device *dev = getSoapyDevice();
|
||||||
|
|
||||||
|
return dev->listAntennas(direction, channel);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
long SDRDeviceInfo::getSampleRateNear(int direction, size_t channel, long sampleRate_in) {
|
long SDRDeviceInfo::getSampleRateNear(int direction, size_t channel, long sampleRate_in) {
|
||||||
std::vector<long> sampleRates = getSampleRates(direction, channel);
|
std::vector<long> sampleRates = getSampleRates(direction, channel);
|
||||||
long returnRate = sampleRates[0];
|
long returnRate = sampleRates[0];
|
||||||
|
@ -83,6 +83,8 @@ public:
|
|||||||
bool hasCORR(int direction, size_t channel);
|
bool hasCORR(int direction, size_t channel);
|
||||||
|
|
||||||
std::vector<long> getSampleRates(int direction, size_t channel);
|
std::vector<long> getSampleRates(int direction, size_t channel);
|
||||||
|
|
||||||
|
std::vector<std::string> getAntennaNames(int direction, size_t channel);
|
||||||
|
|
||||||
long getSampleRateNear(int direction, size_t channel, long sampleRate_in);
|
long getSampleRateNear(int direction, size_t channel, long sampleRate_in);
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ SDRThread::SDRThread() : IOThread(), buffers("SDRThreadBuffers") {
|
|||||||
rate_changed.store(false);
|
rate_changed.store(false);
|
||||||
freq_changed.store(false);
|
freq_changed.store(false);
|
||||||
offset_changed.store(false);
|
offset_changed.store(false);
|
||||||
|
antenna_changed.store(false);
|
||||||
ppm_changed .store(false);
|
ppm_changed .store(false);
|
||||||
device_changed.store(false);
|
device_changed.store(false);
|
||||||
|
|
||||||
@ -437,6 +438,13 @@ void SDRThread::updateSettings() {
|
|||||||
if (!stream) {
|
if (!stream) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (antenna_changed.load()) {
|
||||||
|
|
||||||
|
device->setAntenna(SOAPY_SDR_RX, 0, antennaName);
|
||||||
|
|
||||||
|
antenna_changed.store(false);
|
||||||
|
}
|
||||||
|
|
||||||
if (offset_changed.load()) {
|
if (offset_changed.load()) {
|
||||||
if (!freq_changed.load()) {
|
if (!freq_changed.load()) {
|
||||||
@ -524,7 +532,6 @@ void SDRThread::updateSettings() {
|
|||||||
gain_value_changed.store(false);
|
gain_value_changed.store(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (setting_value_changed.load()) {
|
if (setting_value_changed.load()) {
|
||||||
|
|
||||||
std::lock_guard < std::mutex > lock(setting_busy);
|
std::lock_guard < std::mutex > lock(setting_busy);
|
||||||
@ -652,6 +659,12 @@ void SDRThread::unlockFrequency() {
|
|||||||
void SDRThread::setOffset(long long ofs) {
|
void SDRThread::setOffset(long long ofs) {
|
||||||
offset.store(ofs);
|
offset.store(ofs);
|
||||||
offset_changed.store(true);
|
offset_changed.store(true);
|
||||||
|
|
||||||
|
DeviceConfig *devConfig = deviceConfig.load();
|
||||||
|
if (devConfig) {
|
||||||
|
devConfig->setOffset(ofs);
|
||||||
|
}
|
||||||
|
|
||||||
// std::cout << "Set offset: " << offset.load() << std::endl;
|
// std::cout << "Set offset: " << offset.load() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -659,6 +672,20 @@ long long SDRThread::getOffset() {
|
|||||||
return offset.load();
|
return offset.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SDRThread::setAntenna(const std::string& name) {
|
||||||
|
antennaName = name;
|
||||||
|
antenna_changed.store(true);
|
||||||
|
|
||||||
|
DeviceConfig *devConfig = deviceConfig.load();
|
||||||
|
if (devConfig) {
|
||||||
|
devConfig->setAntennaName(antennaName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SDRThread::getAntenna() {
|
||||||
|
return antennaName;
|
||||||
|
}
|
||||||
|
|
||||||
void SDRThread::setSampleRate(long rate) {
|
void SDRThread::setSampleRate(long rate) {
|
||||||
sampleRate.store(rate);
|
sampleRate.store(rate);
|
||||||
rate_changed = true;
|
rate_changed = true;
|
||||||
@ -675,6 +702,12 @@ long SDRThread::getSampleRate() {
|
|||||||
void SDRThread::setPPM(int ppm) {
|
void SDRThread::setPPM(int ppm) {
|
||||||
this->ppm.store(ppm);
|
this->ppm.store(ppm);
|
||||||
ppm_changed.store(true);
|
ppm_changed.store(true);
|
||||||
|
|
||||||
|
DeviceConfig *devConfig = deviceConfig.load();
|
||||||
|
if (devConfig) {
|
||||||
|
devConfig->setPPM(ppm);
|
||||||
|
}
|
||||||
|
|
||||||
// std::cout << "Set PPM: " << this->ppm.load() << std::endl;
|
// std::cout << "Set PPM: " << this->ppm.load() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +76,9 @@ public:
|
|||||||
|
|
||||||
void setOffset(long long ofs);
|
void setOffset(long long ofs);
|
||||||
long long getOffset();
|
long long getOffset();
|
||||||
|
|
||||||
|
void setAntenna(const std::string& name);
|
||||||
|
std::string getAntenna();
|
||||||
|
|
||||||
void setSampleRate(long rate);
|
void setSampleRate(long rate);
|
||||||
long getSampleRate();
|
long getSampleRate();
|
||||||
@ -119,7 +122,8 @@ protected:
|
|||||||
std::atomic_llong frequency, offset, lock_freq;
|
std::atomic_llong frequency, offset, lock_freq;
|
||||||
std::atomic_int ppm, numElems, mtuElems, numChannels;
|
std::atomic_int ppm, numElems, mtuElems, numChannels;
|
||||||
std::atomic_bool hasPPM, hasHardwareDC;
|
std::atomic_bool hasPPM, hasHardwareDC;
|
||||||
std::atomic_bool agc_mode, rate_changed, freq_changed, offset_changed,
|
std::string antennaName;
|
||||||
|
std::atomic_bool agc_mode, rate_changed, freq_changed, offset_changed, antenna_changed,
|
||||||
ppm_changed, device_changed, agc_mode_changed, gain_value_changed, setting_value_changed, frequency_locked, frequency_lock_init, iq_swap;
|
ppm_changed, device_changed, agc_mode_changed, gain_value_changed, setting_value_changed, frequency_locked, frequency_lock_init, iq_swap;
|
||||||
|
|
||||||
std::mutex gain_busy;
|
std::mutex gain_busy;
|
||||||
|
@ -245,6 +245,7 @@ void TuningCanvas::StepTuner(ActiveState state, int exponent, bool up) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wxGetApp().setPPM(currentPPM);
|
wxGetApp().setPPM(currentPPM);
|
||||||
|
wxGetApp().notifyMainUIOfDeviceChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user