mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2025-07-31 12:52:25 -04:00
commit
364e1333f5
@ -1,36 +1,76 @@
|
||||
#include "AppConfig.h"
|
||||
#include "CubicSDR.h"
|
||||
|
||||
DeviceConfig::DeviceConfig() : ppm(0), deviceId("") {
|
||||
|
||||
DeviceConfig::DeviceConfig() : deviceId("") {
|
||||
ppm.store(0);
|
||||
directSampling.store(false);
|
||||
offset.store(0);
|
||||
}
|
||||
|
||||
DeviceConfig::DeviceConfig(std::string deviceId) : ppm(0) {
|
||||
DeviceConfig::DeviceConfig(std::string deviceId) : DeviceConfig() {
|
||||
this->deviceId = deviceId;
|
||||
}
|
||||
|
||||
void DeviceConfig::setPPM(int ppm) {
|
||||
this->ppm = ppm;
|
||||
this->ppm.store(ppm);
|
||||
}
|
||||
|
||||
int DeviceConfig::getPPM() {
|
||||
return ppm;
|
||||
return ppm.load();
|
||||
}
|
||||
|
||||
void DeviceConfig::setDirectSampling(int mode) {
|
||||
directSampling.store(mode);
|
||||
}
|
||||
|
||||
int DeviceConfig::getDirectSampling() {
|
||||
return directSampling.load();
|
||||
}
|
||||
|
||||
void DeviceConfig::setOffset(long long offset) {
|
||||
this->offset.store(offset);
|
||||
}
|
||||
|
||||
long long DeviceConfig::getOffset() {
|
||||
return offset.load();
|
||||
}
|
||||
|
||||
void DeviceConfig::setIQSwap(bool iqSwap) {
|
||||
this->iqSwap.store(iqSwap);
|
||||
}
|
||||
|
||||
bool DeviceConfig::getIQSwap() {
|
||||
return iqSwap.load();
|
||||
}
|
||||
|
||||
void DeviceConfig::setDeviceId(std::string deviceId) {
|
||||
busy_lock.lock();
|
||||
this->deviceId = deviceId;
|
||||
busy_lock.unlock();
|
||||
}
|
||||
|
||||
std::string DeviceConfig::getDeviceId() {
|
||||
return deviceId;
|
||||
std::string tmp;
|
||||
|
||||
busy_lock.lock();
|
||||
tmp = deviceId;
|
||||
busy_lock.unlock();
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void DeviceConfig::save(DataNode *node) {
|
||||
node->newChild("id")->element()->set(deviceId);
|
||||
DataNode *ppm_node = node->newChild("ppm");
|
||||
ppm_node->element()->set((int)ppm);
|
||||
busy_lock.lock();
|
||||
*node->newChild("id") = deviceId;
|
||||
*node->newChild("ppm") = (int)ppm;
|
||||
*node->newChild("iq_swap") = iqSwap;
|
||||
*node->newChild("direct_sampling") = directSampling;
|
||||
*node->newChild("offset") = offset;
|
||||
busy_lock.unlock();
|
||||
}
|
||||
|
||||
void DeviceConfig::load(DataNode *node) {
|
||||
busy_lock.lock();
|
||||
if (node->hasAnother("ppm")) {
|
||||
DataNode *ppm_node = node->getNext("ppm");
|
||||
int ppmValue = 0;
|
||||
@ -38,11 +78,58 @@ void DeviceConfig::load(DataNode *node) {
|
||||
setPPM(ppmValue);
|
||||
std::cout << "Loaded PPM for device '" << deviceId << "' at " << ppmValue << "ppm" << std::endl;
|
||||
}
|
||||
if (node->hasAnother("iq_swap")) {
|
||||
DataNode *iq_swap_node = node->getNext("iq_swap");
|
||||
int iqSwapValue = 0;
|
||||
iq_swap_node->element()->get(iqSwapValue);
|
||||
setIQSwap(iqSwapValue?true:false);
|
||||
std::cout << "Loaded I/Q Swap for device '" << deviceId << "' as " << (iqSwapValue?"swapped":"not swapped") << std::endl;
|
||||
}
|
||||
if (node->hasAnother("direct_sampling")) {
|
||||
DataNode *direct_sampling_node = node->getNext("direct_sampling");
|
||||
int directSamplingValue = 0;
|
||||
direct_sampling_node->element()->get(directSamplingValue);
|
||||
setDirectSampling(directSamplingValue);
|
||||
std::cout << "Loaded Direct Sampling Mode for device '" << deviceId << "': ";
|
||||
switch (directSamplingValue) {
|
||||
case 0:
|
||||
std::cout << "off" << std::endl;
|
||||
break;
|
||||
case 1:
|
||||
std::cout << "I-ADC" << std::endl;
|
||||
break;
|
||||
case 2:
|
||||
std::cout << "Q-ADC" << std::endl;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
if (node->hasAnother("offset")) {
|
||||
DataNode *offset_node = node->getNext("offset");
|
||||
long long offsetValue = 0;
|
||||
offset_node->element()->get(offsetValue);
|
||||
setOffset(offsetValue);
|
||||
std::cout << "Loaded offset for device '" << deviceId << "' at " << offsetValue << "Hz" << std::endl;
|
||||
}
|
||||
busy_lock.unlock();
|
||||
}
|
||||
|
||||
AppConfig::AppConfig() {
|
||||
winX.store(0);
|
||||
winY.store(0);
|
||||
winW.store(0);
|
||||
winH.store(0);
|
||||
winMax.store(false);
|
||||
themeId.store(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
DeviceConfig *AppConfig::getDevice(std::string deviceId) {
|
||||
DeviceConfig *conf = &deviceConfig[deviceId];
|
||||
if (deviceConfig.find(deviceId) == deviceConfig.end()) {
|
||||
deviceConfig[deviceId] = new DeviceConfig();
|
||||
}
|
||||
DeviceConfig *conf = deviceConfig[deviceId];
|
||||
conf->setDeviceId(deviceId);
|
||||
return conf;
|
||||
}
|
||||
@ -65,18 +152,67 @@ std::string AppConfig::getConfigDir() {
|
||||
return dataDir;
|
||||
}
|
||||
|
||||
|
||||
void AppConfig::setWindow(wxPoint winXY, wxSize winWH) {
|
||||
winX.store(winXY.x);
|
||||
winY.store(winXY.y);
|
||||
winW.store(winWH.x);
|
||||
winH.store(winWH.y);
|
||||
}
|
||||
|
||||
void AppConfig::setWindowMaximized(bool max) {
|
||||
winMax.store(max);
|
||||
}
|
||||
|
||||
bool AppConfig::getWindowMaximized() {
|
||||
return winMax.load();
|
||||
}
|
||||
|
||||
wxRect *AppConfig::getWindow() {
|
||||
wxRect *r = NULL;
|
||||
if (winH.load() && winW.load()) {
|
||||
r = new wxRect(winX.load(),winY.load(),winW.load(),winH.load());
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
void AppConfig::setTheme(int themeId) {
|
||||
this->themeId.store(themeId);
|
||||
}
|
||||
|
||||
int AppConfig::getTheme() {
|
||||
return themeId.load();
|
||||
}
|
||||
|
||||
|
||||
bool AppConfig::save() {
|
||||
DataTree cfg;
|
||||
|
||||
cfg.rootNode()->setName("cubicsdr_config");
|
||||
|
||||
if (winW.load() && winH.load()) {
|
||||
DataNode *window_node = cfg.rootNode()->newChild("window");
|
||||
|
||||
*window_node->newChild("x") = winX.load();
|
||||
*window_node->newChild("y") = winY.load();
|
||||
*window_node->newChild("w") = winW.load();
|
||||
*window_node->newChild("h") = winH.load();
|
||||
|
||||
*window_node->newChild("max") = winMax.load();
|
||||
|
||||
*window_node->newChild("theme") = themeId.load();
|
||||
}
|
||||
|
||||
DataNode *devices_node = cfg.rootNode()->newChild("devices");
|
||||
|
||||
std::map<std::string, DeviceConfig>::iterator device_config_i;
|
||||
std::map<std::string, DeviceConfig *>::iterator device_config_i;
|
||||
for (device_config_i = deviceConfig.begin(); device_config_i != deviceConfig.end(); device_config_i++) {
|
||||
DataNode *device_node = devices_node->newChild("device");
|
||||
device_config_i->second.save(device_node);
|
||||
device_config_i->second->save(device_node);
|
||||
}
|
||||
|
||||
|
||||
std::string cfgFileDir = getConfigDir();
|
||||
|
||||
wxFileName cfgFile = wxFileName(cfgFileDir, "config.xml");
|
||||
@ -110,6 +246,37 @@ bool AppConfig::load() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cfg.rootNode()->hasAnother("window")) {
|
||||
int x,y,w,h;
|
||||
int max;
|
||||
|
||||
DataNode *win_node = cfg.rootNode()->getNext("window");
|
||||
|
||||
if (win_node->hasAnother("w") && win_node->hasAnother("h") && win_node->hasAnother("x") && win_node->hasAnother("y")) {
|
||||
win_node->getNext("x")->element()->get(x);
|
||||
win_node->getNext("y")->element()->get(y);
|
||||
win_node->getNext("w")->element()->get(w);
|
||||
win_node->getNext("h")->element()->get(h);
|
||||
|
||||
winX.store(x);
|
||||
winY.store(y);
|
||||
winW.store(w);
|
||||
winH.store(h);
|
||||
}
|
||||
|
||||
if (win_node->hasAnother("max")) {
|
||||
win_node->getNext("max")->element()->get(max);
|
||||
winMax.store(max?true:false);
|
||||
}
|
||||
|
||||
if (win_node->hasAnother("theme")) {
|
||||
int theme;
|
||||
win_node->getNext("theme")->element()->get(theme);
|
||||
themeId.store(theme);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (cfg.rootNode()->hasAnother("devices")) {
|
||||
DataNode *devices_node = cfg.rootNode()->getNext("devices");
|
||||
|
||||
|
@ -3,10 +3,12 @@
|
||||
#include <wx/stdpaths.h>
|
||||
#include <wx/dir.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/panel.h>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
#include "DataTree.h"
|
||||
|
||||
|
||||
class DeviceConfig {
|
||||
public:
|
||||
DeviceConfig();
|
||||
@ -14,7 +16,16 @@ public:
|
||||
|
||||
void setPPM(int ppm);
|
||||
int getPPM();
|
||||
|
||||
void setDirectSampling(int mode);
|
||||
int getDirectSampling();
|
||||
|
||||
void setOffset(long long offset);
|
||||
long long getOffset();
|
||||
|
||||
void setIQSwap(bool iqSwap);
|
||||
bool getIQSwap();
|
||||
|
||||
void setDeviceId(std::string deviceId);
|
||||
std::string getDeviceId();
|
||||
|
||||
@ -23,18 +34,35 @@ public:
|
||||
|
||||
private:
|
||||
std::string deviceId;
|
||||
int ppm;
|
||||
std::mutex busy_lock;
|
||||
|
||||
std::atomic_int ppm, directSampling;
|
||||
std::atomic_bool iqSwap;
|
||||
std::atomic_llong offset;
|
||||
};
|
||||
|
||||
class AppConfig {
|
||||
public:
|
||||
AppConfig();
|
||||
std::string getConfigDir();
|
||||
DeviceConfig *getDevice(std::string deviceId);
|
||||
|
||||
void setWindow(wxPoint winXY, wxSize winWH);
|
||||
wxRect *getWindow();
|
||||
|
||||
void setWindowMaximized(bool max);
|
||||
bool getWindowMaximized();
|
||||
|
||||
void setTheme(int themeId);
|
||||
int getTheme();
|
||||
|
||||
bool save();
|
||||
bool load();
|
||||
bool reset();
|
||||
|
||||
private:
|
||||
std::map<std::string, DeviceConfig> deviceConfig;
|
||||
std::map<std::string, DeviceConfig *> deviceConfig;
|
||||
std::atomic_int winX,winY,winW,winH;
|
||||
std::atomic_bool winMax;
|
||||
std::atomic_int themeId;
|
||||
};
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
wxBEGIN_EVENT_TABLE(AppFrame, wxFrame)
|
||||
//EVT_MENU(wxID_NEW, AppFrame::OnNewWindow)
|
||||
EVT_MENU(wxID_CLOSE, AppFrame::OnClose)
|
||||
EVT_CLOSE(AppFrame::OnClose)
|
||||
EVT_MENU(wxID_ANY, AppFrame::OnMenu)
|
||||
EVT_COMMAND(wxID_ANY, wxEVT_THREAD, AppFrame::OnThread)
|
||||
EVT_IDLE(AppFrame::OnIdle)
|
||||
@ -152,9 +152,9 @@ AppFrame::AppFrame() :
|
||||
|
||||
wxMenu *dsMenu = new wxMenu;
|
||||
|
||||
dsMenu->AppendRadioItem(wxID_SET_DS_OFF, "Off");
|
||||
dsMenu->AppendRadioItem(wxID_SET_DS_I, "I-ADC");
|
||||
dsMenu->AppendRadioItem(wxID_SET_DS_Q, "Q-ADC");
|
||||
directSamplingMenuItems[0] = dsMenu->AppendRadioItem(wxID_SET_DS_OFF, "Off");
|
||||
directSamplingMenuItems[1] = dsMenu->AppendRadioItem(wxID_SET_DS_I, "I-ADC");
|
||||
directSamplingMenuItems[2] = dsMenu->AppendRadioItem(wxID_SET_DS_Q, "Q-ADC");
|
||||
|
||||
menu->AppendSubMenu(dsMenu, "Direct Sampling");
|
||||
|
||||
@ -191,13 +191,15 @@ AppFrame::AppFrame() :
|
||||
|
||||
menu = new wxMenu;
|
||||
|
||||
menu->AppendRadioItem(wxID_THEME_DEFAULT, "Default")->Check(true);
|
||||
menu->AppendRadioItem(wxID_THEME_RADAR, "RADAR");
|
||||
menu->AppendRadioItem(wxID_THEME_BW, "Black & White");
|
||||
menu->AppendRadioItem(wxID_THEME_SHARP, "Sharp");
|
||||
menu->AppendRadioItem(wxID_THEME_RAD, "Rad");
|
||||
menu->AppendRadioItem(wxID_THEME_TOUCH, "Touch");
|
||||
menu->AppendRadioItem(wxID_THEME_HD, "HD");
|
||||
int themeId = wxGetApp().getConfig()->getTheme();
|
||||
|
||||
menu->AppendRadioItem(wxID_THEME_DEFAULT, "Default")->Check(themeId==COLOR_THEME_DEFAULT);
|
||||
menu->AppendRadioItem(wxID_THEME_RADAR, "RADAR")->Check(themeId==COLOR_THEME_RADAR);
|
||||
menu->AppendRadioItem(wxID_THEME_BW, "Black & White")->Check(themeId==COLOR_THEME_BW);
|
||||
menu->AppendRadioItem(wxID_THEME_SHARP, "Sharp")->Check(themeId==COLOR_THEME_SHARP);
|
||||
menu->AppendRadioItem(wxID_THEME_RAD, "Rad")->Check(themeId==COLOR_THEME_RAD);
|
||||
menu->AppendRadioItem(wxID_THEME_TOUCH, "Touch")->Check(themeId==COLOR_THEME_TOUCH);
|
||||
menu->AppendRadioItem(wxID_THEME_HD, "HD")->Check(themeId==COLOR_THEME_HD);
|
||||
|
||||
menuBar->Append(menu, wxT("&Color Scheme"));
|
||||
|
||||
@ -303,8 +305,23 @@ AppFrame::AppFrame() :
|
||||
SetMenuBar(menuBar);
|
||||
|
||||
CreateStatusBar();
|
||||
SetClientSize(1280, 600);
|
||||
Centre();
|
||||
|
||||
wxRect *win = wxGetApp().getConfig()->getWindow();
|
||||
if (win) {
|
||||
this->SetPosition(win->GetPosition());
|
||||
this->SetClientSize(win->GetSize());
|
||||
} else {
|
||||
SetClientSize(1280, 600);
|
||||
Centre();
|
||||
}
|
||||
bool max = wxGetApp().getConfig()->getWindowMaximized();
|
||||
|
||||
if (max) {
|
||||
this->Maximize();
|
||||
}
|
||||
|
||||
ThemeMgr::mgr.setTheme(wxGetApp().getConfig()->getTheme());
|
||||
|
||||
Show();
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -329,6 +346,22 @@ AppFrame::~AppFrame() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void AppFrame::initDeviceParams(std::string deviceId) {
|
||||
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(deviceId);
|
||||
|
||||
int dsMode = devConfig->getDirectSampling();
|
||||
|
||||
if (dsMode > 0 && dsMode <= 2) {
|
||||
directSamplingMenuItems[devConfig->getDirectSampling()]->Check();
|
||||
}
|
||||
|
||||
if (devConfig->getIQSwap()) {
|
||||
iqSwapMenuItem->Check();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AppFrame::OnMenu(wxCommandEvent& event) {
|
||||
if (event.GetId() >= wxID_RT_AUDIO_DEVICE && event.GetId() < wxID_RT_AUDIO_DEVICE + devices.size()) {
|
||||
if (activeDemodulator) {
|
||||
@ -449,7 +482,19 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
||||
|
||||
std::vector<SDRDeviceInfo *> *devs = wxGetApp().getDevices();
|
||||
if (event.GetId() >= wxID_DEVICE_ID && event.GetId() <= wxID_DEVICE_ID + devs->size()) {
|
||||
wxGetApp().setDevice(event.GetId() - wxID_DEVICE_ID);
|
||||
int devId = event.GetId() - wxID_DEVICE_ID;
|
||||
wxGetApp().setDevice(devId);
|
||||
|
||||
SDRDeviceInfo *dev = (*wxGetApp().getDevices())[devId];
|
||||
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId());
|
||||
|
||||
int dsMode = devConfig->getDirectSampling();
|
||||
|
||||
if (dsMode >= 0 && dsMode <= 2) {
|
||||
directSamplingMenuItems[devConfig->getDirectSampling()]->Check();
|
||||
}
|
||||
|
||||
iqSwapMenuItem->Check(devConfig->getIQSwap());
|
||||
}
|
||||
|
||||
if (event.GetId() >= wxID_AUDIO_BANDWIDTH_BASE) {
|
||||
@ -479,8 +524,12 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
||||
|
||||
}
|
||||
|
||||
void AppFrame::OnClose(wxCommandEvent& WXUNUSED(event)) {
|
||||
Close(false);
|
||||
void AppFrame::OnClose(wxCloseEvent& event) {
|
||||
wxGetApp().getConfig()->setWindow(this->GetPosition(), this->GetClientSize());
|
||||
wxGetApp().getConfig()->setWindowMaximized(this->IsMaximized());
|
||||
wxGetApp().getConfig()->setTheme(ThemeMgr::mgr.getTheme());
|
||||
wxGetApp().getConfig()->save();
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void AppFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event)) {
|
||||
@ -618,7 +667,6 @@ void AppFrame::saveSession(std::string fileName) {
|
||||
DataNode *header = s.rootNode()->newChild("header");
|
||||
*header->newChild("version") = std::string(CUBICSDR_VERSION);
|
||||
*header->newChild("center_freq") = wxGetApp().getFrequency();
|
||||
*header->newChild("offset") = wxGetApp().getOffset();
|
||||
|
||||
DataNode *demods = s.rootNode()->newChild("demodulators");
|
||||
|
||||
@ -657,14 +705,11 @@ bool AppFrame::loadSession(std::string fileName) {
|
||||
|
||||
std::string version(*header->getNext("version"));
|
||||
long long center_freq = *header->getNext("center_freq");
|
||||
long long offset = *header->getNext("offset");
|
||||
|
||||
std::cout << "Loading " << version << " session file" << std::endl;
|
||||
std::cout << "\tCenter Frequency: " << center_freq << std::endl;
|
||||
std::cout << "\tOffset: " << offset << std::endl;
|
||||
|
||||
wxGetApp().setFrequency(center_freq);
|
||||
wxGetApp().setOffset(offset);
|
||||
|
||||
DataNode *demodulators = l.rootNode()->getNext("demodulators");
|
||||
|
||||
@ -712,7 +757,7 @@ bool AppFrame::loadSession(std::string fileName) {
|
||||
}
|
||||
|
||||
newDemod->run();
|
||||
|
||||
newDemod->setActive(false);
|
||||
wxGetApp().bindDemodulator(newDemod);
|
||||
|
||||
std::cout << "\tAdded demodulator at frequency " << freq << " type " << type << std::endl;
|
||||
|
@ -58,13 +58,14 @@ public:
|
||||
~AppFrame();
|
||||
void OnThread(wxCommandEvent& event);
|
||||
void OnEventInput(wxThreadEvent& event);
|
||||
void initDeviceParams(std::string deviceId);
|
||||
|
||||
void saveSession(std::string fileName);
|
||||
bool loadSession(std::string fileName);
|
||||
|
||||
private:
|
||||
void OnMenu(wxCommandEvent& event);
|
||||
void OnClose(wxCommandEvent& event);
|
||||
void OnClose(wxCloseEvent& event);
|
||||
void OnNewWindow(wxCommandEvent& event);
|
||||
void OnIdle(wxIdleEvent& event);
|
||||
|
||||
@ -86,6 +87,7 @@ private:
|
||||
std::map<int, wxMenuItem *> outputDeviceMenuItems;
|
||||
std::map<int, wxMenuItem *> sampleRateMenuItems;
|
||||
std::map<int, wxMenuItem *> audioSampleRateMenuItems;
|
||||
std::map<int, wxMenuItem *> directSamplingMenuItems;
|
||||
wxMenuItem *iqSwapMenuItem;
|
||||
|
||||
std::string currentSessionFile;
|
||||
|
@ -67,6 +67,7 @@ bool CubicSDR::OnInit() {
|
||||
std::vector<SDRDeviceInfo *>::iterator devs_i;
|
||||
|
||||
SDRThread::enumerate_rtl(&devs);
|
||||
SDRDeviceInfo *dev = NULL;
|
||||
|
||||
if (devs.size() > 1) {
|
||||
wxArrayString choices;
|
||||
@ -84,16 +85,36 @@ bool CubicSDR::OnInit() {
|
||||
choices.Add(devName);
|
||||
}
|
||||
|
||||
int devId = wxGetSingleChoiceIndex(wxT("Devices"), wxT("Choose Input Device"), choices);
|
||||
int devId = wxGetSingleChoiceIndex(wxT("Devices"), wxT("Choose Input Device"), choices);
|
||||
if (devId == -1) { // User chose to cancel
|
||||
return false;
|
||||
}
|
||||
|
||||
dev = devs[devId];
|
||||
|
||||
std::cout << "Chosen: " << devId << std::endl;
|
||||
sdrThread->setDeviceId(devId);
|
||||
} else if (devs.size() == 1) {
|
||||
dev = devs[0];
|
||||
}
|
||||
|
||||
if (!dev) {
|
||||
wxMessageDialog *info;
|
||||
info = new wxMessageDialog(NULL, wxT("\x28\u256F\xB0\u25A1\xB0\uFF09\u256F\uFE35\x20\u253B\u2501\u253B"), wxT("RTL-SDR device not found"), wxOK | wxICON_ERROR);
|
||||
info->ShowModal();
|
||||
return false;
|
||||
}
|
||||
|
||||
t_PostSDR = new std::thread(&SDRPostThread::threadMain, sdrPostThread);
|
||||
t_SDR = new std::thread(&SDRThread::threadMain, sdrThread);
|
||||
|
||||
appframe = new AppFrame();
|
||||
if (dev != NULL) {
|
||||
appframe->initDeviceParams(dev->getDeviceId());
|
||||
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId());
|
||||
ppm = devConfig->getPPM();
|
||||
offset = devConfig->getOffset();
|
||||
directSamplingMode = devConfig->getDirectSampling();
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
int main_policy;
|
||||
@ -169,6 +190,10 @@ void CubicSDR::setOffset(long long ofs) {
|
||||
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_OFFSET);
|
||||
command.llong_value = ofs;
|
||||
threadCmdQueueSDR->push(command);
|
||||
|
||||
SDRDeviceInfo *dev = (*getDevices())[getDevice()];
|
||||
config.getDevice(dev->getDeviceId())->setOffset(ofs);
|
||||
config.save();
|
||||
}
|
||||
|
||||
void CubicSDR::setDirectSampling(int mode) {
|
||||
@ -176,6 +201,10 @@ void CubicSDR::setDirectSampling(int mode) {
|
||||
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_DIRECT_SAMPLING);
|
||||
command.llong_value = mode;
|
||||
threadCmdQueueSDR->push(command);
|
||||
|
||||
SDRDeviceInfo *dev = (*getDevices())[getDevice()];
|
||||
config.getDevice(dev->getDeviceId())->setDirectSampling(mode);
|
||||
config.save();
|
||||
}
|
||||
|
||||
int CubicSDR::getDirectSampling() {
|
||||
@ -184,6 +213,9 @@ int CubicSDR::getDirectSampling() {
|
||||
|
||||
void CubicSDR::setSwapIQ(bool swapIQ) {
|
||||
sdrPostThread->setSwapIQ(swapIQ);
|
||||
SDRDeviceInfo *dev = (*getDevices())[getDevice()];
|
||||
config.getDevice(dev->getDeviceId())->setIQSwap(swapIQ);
|
||||
config.save();
|
||||
}
|
||||
|
||||
bool CubicSDR::getSwapIQ() {
|
||||
@ -244,11 +276,12 @@ void CubicSDR::setDevice(int deviceId) {
|
||||
threadCmdQueueSDR->push(command);
|
||||
|
||||
SDRDeviceInfo *dev = (*getDevices())[deviceId];
|
||||
DeviceConfig *devConfig = config.getDevice(dev->getDeviceId());
|
||||
|
||||
SDRThreadCommand command_ppm(SDRThreadCommand::SDR_THREAD_CMD_SET_PPM);
|
||||
ppm = config.getDevice(dev->getDeviceId())->getPPM();
|
||||
command_ppm.llong_value = ppm;
|
||||
threadCmdQueueSDR->push(command_ppm);
|
||||
setPPM(devConfig->getPPM());
|
||||
setDirectSampling(devConfig->getDirectSampling());
|
||||
setSwapIQ(devConfig->getIQSwap());
|
||||
setOffset(devConfig->getOffset());
|
||||
}
|
||||
|
||||
int CubicSDR::getDevice() {
|
||||
|
@ -65,7 +65,7 @@ std::string FrequencyDialog::frequencyToStr(long long freq) {
|
||||
}
|
||||
|
||||
long long FrequencyDialog::strToFrequency(std::string freqStr) {
|
||||
std::string filterStr = filterChars(freqStr, std::string("0123456789.MKGmkg"));
|
||||
std::string filterStr = filterChars(freqStr, std::string("0123456789.MKGHmkgh"));
|
||||
|
||||
int numLen = filterStr.find_first_not_of("0123456789.");
|
||||
|
||||
@ -90,8 +90,10 @@ long long FrequencyDialog::strToFrequency(std::string freqStr) {
|
||||
freqTemp *= 1.0e6;
|
||||
} else if (suffixStr.find_first_of("Kk") != std::string::npos) {
|
||||
freqTemp *= 1.0e3;
|
||||
} else if (suffixStr.find_first_of("Hh") != std::string::npos) {
|
||||
// ...
|
||||
}
|
||||
} else if (numPartStr.find_first_of(".") != std::string::npos) {
|
||||
} else if (numPartStr.find_first_of(".") != std::string::npos || freqTemp <= 3000) {
|
||||
freqTemp *= 1.0e6;
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
SDRThread::SDRThread(SDRThreadCommandQueue* pQueue) :
|
||||
commandQueue(pQueue), iqDataOutQueue(NULL), terminated(false), offset(0), deviceId(-1) {
|
||||
dev = NULL;
|
||||
sampleRate = DEFAULT_SAMPLE_RATE;
|
||||
sampleRate.store(DEFAULT_SAMPLE_RATE);
|
||||
}
|
||||
|
||||
SDRThread::~SDRThread() {
|
||||
@ -122,6 +122,7 @@ void SDRThread::threadMain() {
|
||||
std::cout << "SDR thread initializing.." << std::endl;
|
||||
|
||||
int devCount = rtlsdr_get_device_count();
|
||||
|
||||
std::vector<SDRDeviceInfo *> devs;
|
||||
if (deviceId == -1) {
|
||||
deviceId = enumerate_rtl(&devs);
|
||||
@ -136,16 +137,20 @@ void SDRThread::threadMain() {
|
||||
std::cout << "Using device #" << deviceId << std::endl;
|
||||
}
|
||||
|
||||
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(devs[deviceId]->getDeviceId());
|
||||
|
||||
signed char buf[BUF_SIZE];
|
||||
|
||||
long long frequency = DEFAULT_FREQ;
|
||||
int ppm = wxGetApp().getConfig()->getDevice(devs[deviceId]->getDeviceId())->getPPM();
|
||||
int direct_sampling_mode = 0;
|
||||
int ppm = devConfig->getPPM();
|
||||
int direct_sampling_mode = devConfig->getDirectSampling();;
|
||||
int buf_size = BUF_SIZE;
|
||||
|
||||
offset.store(devConfig->getOffset());
|
||||
wxGetApp().setSwapIQ(devConfig->getIQSwap());
|
||||
|
||||
rtlsdr_open(&dev, deviceId);
|
||||
rtlsdr_set_sample_rate(dev, sampleRate);
|
||||
rtlsdr_set_center_freq(dev, frequency - offset);
|
||||
rtlsdr_set_sample_rate(dev, sampleRate.load());
|
||||
rtlsdr_set_center_freq(dev, frequency - offset.load());
|
||||
rtlsdr_set_freq_correction(dev, ppm);
|
||||
rtlsdr_set_agc_mode(dev, 1);
|
||||
rtlsdr_set_offset_tuning(dev, 0);
|
||||
@ -153,7 +158,7 @@ void SDRThread::threadMain() {
|
||||
|
||||
// sampleRate = rtlsdr_get_sample_rate(dev);
|
||||
|
||||
std::cout << "Sample Rate is: " << sampleRate << std::endl;
|
||||
std::cout << "Sample Rate is: " << sampleRate.load() << std::endl;
|
||||
|
||||
int n_read;
|
||||
double seconds = 0.0;
|
||||
@ -174,8 +179,8 @@ void SDRThread::threadMain() {
|
||||
bool ppm_changed = false;
|
||||
bool direct_sampling_changed = false;
|
||||
long long new_freq = frequency;
|
||||
long long new_offset = offset;
|
||||
long long new_rate = sampleRate;
|
||||
long long new_offset = offset.load();
|
||||
long long new_rate = sampleRate.load();
|
||||
int new_device = deviceId;
|
||||
int new_ppm = ppm;
|
||||
|
||||
@ -187,8 +192,8 @@ void SDRThread::threadMain() {
|
||||
case SDRThreadCommand::SDR_THREAD_CMD_TUNE:
|
||||
freq_changed = true;
|
||||
new_freq = command.llong_value;
|
||||
if (new_freq < sampleRate / 2) {
|
||||
new_freq = sampleRate / 2;
|
||||
if (new_freq < sampleRate.load() / 2) {
|
||||
new_freq = sampleRate.load() / 2;
|
||||
}
|
||||
// std::cout << "Set frequency: " << new_freq << std::endl;
|
||||
break;
|
||||
@ -231,8 +236,8 @@ void SDRThread::threadMain() {
|
||||
if (device_changed) {
|
||||
rtlsdr_close(dev);
|
||||
rtlsdr_open(&dev, new_device);
|
||||
rtlsdr_set_sample_rate(dev, sampleRate);
|
||||
rtlsdr_set_center_freq(dev, frequency - offset);
|
||||
rtlsdr_set_sample_rate(dev, sampleRate.load());
|
||||
rtlsdr_set_center_freq(dev, frequency - offset.load());
|
||||
rtlsdr_set_freq_correction(dev, ppm);
|
||||
rtlsdr_set_agc_mode(dev, 1);
|
||||
rtlsdr_set_offset_tuning(dev, 0);
|
||||
@ -244,16 +249,16 @@ void SDRThread::threadMain() {
|
||||
new_freq = frequency;
|
||||
freq_changed = true;
|
||||
}
|
||||
offset = new_offset;
|
||||
offset.store(new_offset);
|
||||
}
|
||||
if (rate_changed) {
|
||||
rtlsdr_set_sample_rate(dev, new_rate);
|
||||
rtlsdr_reset_buffer(dev);
|
||||
sampleRate = rtlsdr_get_sample_rate(dev);
|
||||
sampleRate.store(rtlsdr_get_sample_rate(dev));
|
||||
}
|
||||
if (freq_changed) {
|
||||
frequency = new_freq;
|
||||
rtlsdr_set_center_freq(dev, frequency - offset);
|
||||
rtlsdr_set_center_freq(dev, frequency - offset.load());
|
||||
}
|
||||
if (ppm_changed) {
|
||||
ppm = new_ppm;
|
||||
@ -283,7 +288,7 @@ void SDRThread::threadMain() {
|
||||
// std::lock_guard < std::mutex > lock(dataOut->m_mutex);
|
||||
dataOut->setRefCount(1);
|
||||
dataOut->frequency = frequency;
|
||||
dataOut->sampleRate = sampleRate;
|
||||
dataOut->sampleRate = sampleRate.load();
|
||||
|
||||
if (dataOut->data.capacity() < n_read) {
|
||||
dataOut->data.reserve(n_read);
|
||||
@ -295,7 +300,7 @@ void SDRThread::threadMain() {
|
||||
|
||||
memcpy(&dataOut->data[0], buf, n_read);
|
||||
|
||||
double time_slice = (double) n_read / (double) sampleRate;
|
||||
double time_slice = (double) n_read / (double) sampleRate.load();
|
||||
seconds += time_slice;
|
||||
|
||||
if (iqDataOutQueue.load() != NULL) {
|
||||
|
@ -140,19 +140,19 @@ public:
|
||||
void terminate();
|
||||
|
||||
int getDeviceId() const {
|
||||
return deviceId;
|
||||
return deviceId.load();
|
||||
}
|
||||
|
||||
void setDeviceId(int deviceId) {
|
||||
this->deviceId = deviceId;
|
||||
this->deviceId.store(deviceId);
|
||||
}
|
||||
|
||||
protected:
|
||||
uint32_t sampleRate;
|
||||
long long offset;
|
||||
std::atomic<uint32_t> sampleRate;
|
||||
std::atomic<long long> offset;
|
||||
std::atomic<SDRThreadCommandQueue*> commandQueue;
|
||||
std::atomic<SDRThreadIQDataQueue*> iqDataOutQueue;
|
||||
|
||||
std::atomic<bool> terminated;
|
||||
int deviceId;
|
||||
std::atomic<int> deviceId;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user