From b762d4d118fee3a01acd1512718affb033f06916 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Wed, 8 Jul 2015 01:07:39 -0400 Subject: [PATCH 1/6] Save offset, direct sampling mode and i/q swap per device --- src/AppConfig.cpp | 68 ++++++++++++++++++++++++++++++++++++++++--- src/AppConfig.h | 13 ++++++++- src/AppFrame.cpp | 34 +++++++++++++++++++--- src/AppFrame.h | 1 + src/CubicSDR.cpp | 20 ++++++++++--- src/sdr/SDRThread.cpp | 41 ++++++++++++++------------ src/sdr/SDRThread.h | 10 +++---- 7 files changed, 151 insertions(+), 36 deletions(-) diff --git a/src/AppConfig.cpp b/src/AppConfig.cpp index 88df676..a88353a 100644 --- a/src/AppConfig.cpp +++ b/src/AppConfig.cpp @@ -1,6 +1,7 @@ #include "AppConfig.h" +#include "CubicSDR.h" -DeviceConfig::DeviceConfig() : ppm(0), deviceId("") { +DeviceConfig::DeviceConfig() : deviceId(""), ppm(0), directSampling(false), offset(0) { } @@ -16,6 +17,30 @@ int DeviceConfig::getPPM() { return ppm; } +void DeviceConfig::setDirectSampling(int mode) { + directSampling = mode; +} + +int DeviceConfig::getDirectSampling() { + return directSampling; +} + +void DeviceConfig::setOffset(long long offset) { + this->offset = offset; +} + +long long DeviceConfig::getOffset() { + return offset; +} + +void DeviceConfig::setIQSwap(bool iqSwap) { + this->iqSwap = iqSwap; +} + +bool DeviceConfig::getIQSwap() { + return iqSwap; +} + void DeviceConfig::setDeviceId(std::string deviceId) { this->deviceId = deviceId; } @@ -25,9 +50,11 @@ std::string DeviceConfig::getDeviceId() { } void DeviceConfig::save(DataNode *node) { - node->newChild("id")->element()->set(deviceId); - DataNode *ppm_node = node->newChild("ppm"); - ppm_node->element()->set((int)ppm); + *node->newChild("id") = deviceId; + *node->newChild("ppm") = (int)ppm; + *node->newChild("iq_swap") = iqSwap; + *node->newChild("direct_sampling") = directSampling; + *node->newChild("offset") = offset; } void DeviceConfig::load(DataNode *node) { @@ -38,6 +65,39 @@ 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 << "ppm" << std::endl; + } } diff --git a/src/AppConfig.h b/src/AppConfig.h index 13e5ce1..8e55fd3 100644 --- a/src/AppConfig.h +++ b/src/AppConfig.h @@ -14,7 +14,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,7 +32,9 @@ public: private: std::string deviceId; - int ppm; + int ppm, directSampling; + bool iqSwap; + long long offset; }; class AppConfig { diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index b659b0f..92bc87f 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -151,9 +151,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"); @@ -319,6 +319,20 @@ AppFrame::AppFrame() : wxAcceleratorTable accel(3, entries); SetAcceleratorTable(accel); + SDRDeviceInfo *dev = (*wxGetApp().getDevices())[wxGetApp().getDevice()]; + DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId()); + + int dsMode = devConfig->getDirectSampling(); + + if (dsMode > 0 && dsMode <= 2) { + directSamplingMenuItems[devConfig->getDirectSampling()]->Check(); + } + + if (devConfig->getIQSwap()) { + iqSwapMenuItem->Check(); + } + + // static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 }; // wxLogStatus("Double-buffered display %s supported", wxGLCanvas::IsDisplaySupported(attribs) ? "is" : "not"); // ShowFullScreen(true); @@ -448,7 +462,19 @@ void AppFrame::OnMenu(wxCommandEvent& event) { std::vector *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) { diff --git a/src/AppFrame.h b/src/AppFrame.h index 5788bb7..751da2a 100644 --- a/src/AppFrame.h +++ b/src/AppFrame.h @@ -86,6 +86,7 @@ private: std::map outputDeviceMenuItems; std::map sampleRateMenuItems; std::map audioSampleRateMenuItems; + std::map directSamplingMenuItems; wxMenuItem *iqSwapMenuItem; std::string currentSessionFile; diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 64432bc..874d713 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -169,6 +169,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 +180,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 +192,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 +255,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() { diff --git a/src/sdr/SDRThread.cpp b/src/sdr/SDRThread.cpp index d6771e1..0d8a1bd 100644 --- a/src/sdr/SDRThread.cpp +++ b/src/sdr/SDRThread.cpp @@ -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 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) { diff --git a/src/sdr/SDRThread.h b/src/sdr/SDRThread.h index 135fb90..9bea334 100644 --- a/src/sdr/SDRThread.h +++ b/src/sdr/SDRThread.h @@ -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 sampleRate; + std::atomic offset; std::atomic commandQueue; std::atomic iqDataOutQueue; std::atomic terminated; - int deviceId; + std::atomic deviceId; }; From f86950b334309ffd60cd1824779084420a9fbc4a Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Wed, 8 Jul 2015 18:54:52 -0400 Subject: [PATCH 2/6] Fix startup config access issues, init race --- src/AppConfig.cpp | 32 ++++++++++++++++++++++---------- src/AppConfig.h | 11 +++++++---- src/AppFrame.cpp | 22 ++++++++++++---------- src/AppFrame.h | 1 + src/CubicSDR.cpp | 15 ++++++++++++++- 5 files changed, 56 insertions(+), 25 deletions(-) diff --git a/src/AppConfig.cpp b/src/AppConfig.cpp index a88353a..446aaac 100644 --- a/src/AppConfig.cpp +++ b/src/AppConfig.cpp @@ -10,54 +10,65 @@ DeviceConfig::DeviceConfig(std::string deviceId) : ppm(0) { } 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 = mode; + directSampling.store(mode); } int DeviceConfig::getDirectSampling() { - return directSampling; + return directSampling.load(); } void DeviceConfig::setOffset(long long offset) { - this->offset = offset; + this->offset.store(offset); } long long DeviceConfig::getOffset() { - return offset; + return offset.load(); } void DeviceConfig::setIQSwap(bool iqSwap) { - this->iqSwap = iqSwap; + this->iqSwap.store(iqSwap); } bool DeviceConfig::getIQSwap() { - return iqSwap; + 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) { + 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; @@ -96,8 +107,9 @@ void DeviceConfig::load(DataNode *node) { long long offsetValue = 0; offset_node->element()->get(offsetValue); setOffset(offsetValue); - std::cout << "Loaded offset for device '" << deviceId << "' at " << offsetValue << "ppm" << std::endl; + std::cout << "Loaded offset for device '" << deviceId << "' at " << offsetValue << "Hz" << std::endl; } + busy_lock.unlock(); } diff --git a/src/AppConfig.h b/src/AppConfig.h index 8e55fd3..baebdff 100644 --- a/src/AppConfig.h +++ b/src/AppConfig.h @@ -3,10 +3,11 @@ #include #include #include +#include +#include #include "DataTree.h" - class DeviceConfig { public: DeviceConfig(); @@ -32,9 +33,11 @@ public: private: std::string deviceId; - int ppm, directSampling; - bool iqSwap; - long long offset; + std::mutex busy_lock; + + std::atomic ppm, directSampling; + std::atomic iqSwap; + std::atomic offset; }; class AppConfig { diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 92bc87f..64365d1 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -319,8 +319,18 @@ AppFrame::AppFrame() : wxAcceleratorTable accel(3, entries); SetAcceleratorTable(accel); - SDRDeviceInfo *dev = (*wxGetApp().getDevices())[wxGetApp().getDevice()]; - DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId()); +// static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 }; +// wxLogStatus("Double-buffered display %s supported", wxGLCanvas::IsDisplaySupported(attribs) ? "is" : "not"); +// ShowFullScreen(true); +} + +AppFrame::~AppFrame() { + +} + + +void AppFrame::initDeviceParams(std::string deviceId) { + DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(deviceId); int dsMode = devConfig->getDirectSampling(); @@ -331,16 +341,8 @@ AppFrame::AppFrame() : if (devConfig->getIQSwap()) { iqSwapMenuItem->Check(); } - - -// static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 }; -// wxLogStatus("Double-buffered display %s supported", wxGLCanvas::IsDisplaySupported(attribs) ? "is" : "not"); -// ShowFullScreen(true); } -AppFrame::~AppFrame() { - -} void AppFrame::OnMenu(wxCommandEvent& event) { if (event.GetId() >= wxID_RT_AUDIO_DEVICE && event.GetId() < wxID_RT_AUDIO_DEVICE + devices.size()) { diff --git a/src/AppFrame.h b/src/AppFrame.h index 751da2a..ebae67e 100644 --- a/src/AppFrame.h +++ b/src/AppFrame.h @@ -58,6 +58,7 @@ 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); diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 874d713..659e3e5 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -67,6 +67,7 @@ bool CubicSDR::OnInit() { std::vector::iterator devs_i; SDRThread::enumerate_rtl(&devs); + SDRDeviceInfo *dev = NULL; if (devs.size() > 1) { wxArrayString choices; @@ -78,6 +79,9 @@ bool CubicSDR::OnInit() { devName.append(" ["); devName.append((*devs_i)->getSerial()); devName.append("]"); + if (!dev) { + dev = (*devs_i); + } } else { devName.append(" (In Use?)"); } @@ -85,15 +89,24 @@ bool CubicSDR::OnInit() { } int devId = wxGetSingleChoiceIndex(wxT("Devices"), wxT("Choose Input Device"), choices); + dev = devs[devId]; - std::cout << "Chosen: " << devId << std::endl; sdrThread->setDeviceId(devId); + } else if (devs.size() == 1) { + dev = devs[0]; } 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; From 6e20f1168048fdc915a54f12b64be96e2afcfa8a Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Wed, 8 Jul 2015 19:25:22 -0400 Subject: [PATCH 3/6] Deprecate offset setting in session to avoid device conflict Possible fix for session loading memory leak; may sometimes buffer IQ data to demodulators loaded outside of the current center and bandwidth that should be inactive. --- src/AppFrame.cpp | 6 +----- src/CubicSDR.cpp | 3 --- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 64365d1..f2eba43 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -645,7 +645,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"); @@ -684,14 +683,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"); @@ -739,7 +735,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; diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 659e3e5..64cf57a 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -79,9 +79,6 @@ bool CubicSDR::OnInit() { devName.append(" ["); devName.append((*devs_i)->getSerial()); devName.append("]"); - if (!dev) { - dev = (*devs_i); - } } else { devName.append(" (In Use?)"); } From 1fdaa112ea63f3189a227ed3da0a5f0535b600a9 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Wed, 8 Jul 2015 23:32:30 -0400 Subject: [PATCH 4/6] basic startup tweaks... ;) --- src/CubicSDR.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 64cf57a..3e47710 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -85,13 +85,24 @@ 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]; 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); From f41c14f56c5a4625849599944ab1f517a935a0d8 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Tue, 14 Jul 2015 19:44:19 -0400 Subject: [PATCH 5/6] linux gcc error related fixes --- src/AppConfig.cpp | 9 ++++++--- src/AppConfig.h | 8 ++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/AppConfig.cpp b/src/AppConfig.cpp index 446aaac..d49b8c9 100644 --- a/src/AppConfig.cpp +++ b/src/AppConfig.cpp @@ -114,7 +114,10 @@ void DeviceConfig::load(DataNode *node) { 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; } @@ -143,10 +146,10 @@ bool AppConfig::save() { cfg.rootNode()->setName("cubicsdr_config"); DataNode *devices_node = cfg.rootNode()->newChild("devices"); - std::map::iterator device_config_i; + std::map::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(); diff --git a/src/AppConfig.h b/src/AppConfig.h index baebdff..f1bff72 100644 --- a/src/AppConfig.h +++ b/src/AppConfig.h @@ -35,9 +35,9 @@ private: std::string deviceId; std::mutex busy_lock; - std::atomic ppm, directSampling; - std::atomic iqSwap; - std::atomic offset; + std::atomic_int ppm, directSampling; + std::atomic_bool iqSwap; + std::atomic_llong offset; }; class AppConfig { @@ -50,5 +50,5 @@ public: bool reset(); private: - std::map deviceConfig; + std::map deviceConfig; }; From 425927fb9eb7e1ad67a8ce68f673ebbfd7b257fd Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Tue, 14 Jul 2015 20:27:32 -0400 Subject: [PATCH 6/6] visual studio fixes --- src/AppConfig.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/AppConfig.cpp b/src/AppConfig.cpp index d49b8c9..11b4088 100644 --- a/src/AppConfig.cpp +++ b/src/AppConfig.cpp @@ -1,11 +1,13 @@ #include "AppConfig.h" #include "CubicSDR.h" -DeviceConfig::DeviceConfig() : deviceId(""), ppm(0), directSampling(false), offset(0) { - +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; }