Separate SDR data thread and enumeration, device dialog

This commit is contained in:
Charles J. Cliffe 2015-10-04 16:07:14 -04:00
parent 4ce8bc1781
commit bf9695ecd3
14 changed files with 1247 additions and 725 deletions

View File

@ -267,6 +267,7 @@ SET (cubicsdr_sources
src/IOThread.cpp
src/sdr/SDRDeviceInfo.cpp
src/sdr/SDRPostThread.cpp
src/sdr/SDREnumerator.cpp
src/demod/DemodulatorPreThread.cpp
src/demod/DemodulatorThread.cpp
src/demod/DemodulatorWorkerThread.cpp
@ -322,6 +323,7 @@ SET (cubicsdr_headers
src/IOThread.h
src/sdr/SDRDeviceInfo.h
src/sdr/SDRPostThread.h
src/sdr/SDREnumerator.h
src/demod/DemodulatorPreThread.h
src/demod/DemodulatorThread.h
src/demod/DemodulatorWorkerThread.h

View File

@ -210,6 +210,7 @@ AppFrame::AppFrame() :
menu = new wxMenu;
menu->Append(wxID_SDR_DEVICES, "SDR Devices");
menu->Append(wxID_SET_FREQ_OFFSET, "Frequency Offset");
menu->Append(wxID_SET_PPM, "Device PPM");
iqSwapMenuItem = menu->AppendCheckItem(wxID_SET_SWAP_IQ, "Swap I/Q");
@ -468,6 +469,8 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
wxGetApp().setSwapIQ(swap_state);
wxGetApp().saveConfig();
iqSwapMenuItem->Check(swap_state);
} else if (event.GetId() == wxID_SDR_DEVICES) {
wxGetApp().deviceSelector();
} else if (event.GetId() == wxID_SET_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);
@ -585,29 +588,30 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
wxGetApp().setSampleRate(3200000);
break;
case wxID_BANDWIDTH_MANUAL:
long bw = wxGetNumberFromUser("Set the bandwidth manually", "Sample Rate (Hz), i.e. 2560000 for 2.56M", "Manual Bandwidth Entry", wxGetApp().getSampleRate(), 250000, 25000000, this);
long bw = wxGetNumberFromUser("Set the bandwidth manually", "Sample Rate (Hz), i.e. 2560000 for 2.56M",
"Manual Bandwidth Entry", wxGetApp().getSampleRate(), 250000, 25000000, this);
if (bw != -1) {
wxGetApp().setSampleRate(bw);
}
break;
}
std::vector<SDRDeviceInfo *> *devs = wxGetApp().getDevices();
if (event.GetId() >= wxID_DEVICE_ID && event.GetId() <= wxID_DEVICE_ID + devs->size()) {
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());
}
// std::vector<SDRDeviceInfo *> *devs = wxGetApp().getDevices();
// if (event.GetId() >= wxID_DEVICE_ID && event.GetId() <= wxID_DEVICE_ID + devs->size()) {
// 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) {
int evId = event.GetId();

View File

@ -22,6 +22,7 @@
#define wxID_SET_DS_I 2005
#define wxID_SET_DS_Q 2006
#define wxID_SET_SWAP_IQ 2007
#define wxID_SDR_DEVICES 2008
#define wxID_THEME_DEFAULT 2100
#define wxID_THEME_SHARP 2101

View File

@ -18,6 +18,8 @@
#include "CoreFoundation/CoreFoundation.h"
#endif
#include <SDRDevices.h>
IMPLEMENT_APP(CubicSDR)
CubicSDR::CubicSDR() : appframe(NULL), m_glContext(NULL), frequency(0), offset(0), ppm(0), snap(1), sampleRate(DEFAULT_SAMPLE_RATE), directSamplingMode(0),
@ -96,8 +98,11 @@ bool CubicSDR::OnInit() {
t_SpectrumVisual = new std::thread(&SpectrumVisualDataThread::threadMain, spectrumVisualThread);
t_DemodVisual = new std::thread(&SpectrumVisualDataThread::threadMain, demodVisualThread);
t_SDR = new std::thread(&SDRThread::threadMain, sdrThread);
// t_SDR = new std::thread(&SDRThread::threadMain, sdrThread);
sdrEnum = new SDREnumerator();
t_SDREnum = new std::thread(&SDREnumerator::threadMain, sdrEnum);
appframe = new AppFrame();
#ifdef __APPLE__
@ -119,7 +124,9 @@ int CubicSDR::OnExit() {
std::cout << "Terminating SDR thread.." << std::endl;
if (!sdrThread->isTerminated()) {
sdrThread->terminate();
t_SDR->join();
if (t_SDR) {
t_SDR->join();
}
}
std::cout << "Terminating SDR post-processing thread.." << std::endl;
sdrPostThread->terminate();
@ -183,68 +190,15 @@ bool CubicSDR::OnCmdLineParsed(wxCmdLineParser& parser) {
return true;
}
SDRDeviceInfo *CubicSDR::deviceSelector() {
std::vector<SDRDeviceInfo *>::iterator devs_i;
SDRDeviceInfo *dev = NULL;
devs = SDRThread::enumerate_devices();
if (devs->size() > 1) {
wxArrayString choices;
for (devs_i = devs->begin(); devs_i != devs->end(); devs_i++) {
std::string devName = (*devs_i)->getName();
if ((*devs_i)->isAvailable()) {
// devName.append(": ");
// devName.append((*devs_i)->getProduct());
// devName.append(" [");
// devName.append((*devs_i)->getSerial());
// devName.append("]");
} else {
devName.append(" (In Use?)");
}
choices.Add(devName);
}
int devId = wxGetSingleChoiceIndex(wxT("Devices"), wxT("Choose Input Device"), choices);
if (devId == -1) { // User chose to cancel
return NULL;
}
dev = (*devs)[devId];
} else if (devs->size() == 1) {
dev = (*devs)[0];
void CubicSDR::deviceSelector() {
if (sdrEnum->isTerminated()) {
devs = SDREnumerator::enumerate_devices();
SDRDevicesDialog *dlg = new SDRDevicesDialog(appframe);
dlg->Show();
}
if (dev == NULL) {
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 NULL;
}
return dev;
}
void CubicSDR::sdrThreadNotify(SDRThread::SDRThreadState state, std::string message) {
if (state == SDRThread::SDR_THREAD_DEVICES_READY) {
SDRDeviceInfo *dev = deviceSelector();
if (dev) {
appframe->initDeviceParams(dev->getDeviceId());
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId());
ppm = devConfig->getPPM();
offset = devConfig->getOffset();
directSamplingMode = devConfig->getDirectSampling();
sdrThread->setDevice(dev);
if (t_SDR) {
delete t_SDR;
}
t_SDR = new std::thread(&SDRThread::threadMain, sdrThread);
}
}
if (state == SDRThread::SDR_THREAD_NO_DEVICES) {
}
if (state == SDRThread::SDR_THREAD_TERMINATED) {
t_SDR->join();
delete t_SDR;
@ -256,6 +210,20 @@ void CubicSDR::sdrThreadNotify(SDRThread::SDRThreadState state, std::string mess
}
}
void CubicSDR::sdrEnumThreadNotify(SDREnumerator::SDREnumState state, std::string message) {
if (state == SDREnumerator::SDR_ENUM_DEVICES_READY) {
deviceSelector();
}
if (state == SDREnumerator::SDR_ENUM_FAILED) {
sdrEnum->terminate();
wxMessageDialog *info;
info = new wxMessageDialog(NULL, message, wxT("Error enumerating devices"), wxOK | wxICON_ERROR);
info->ShowModal();
}
}
void CubicSDR::setFrequency(long long freq) {
if (freq < sampleRate / 2) {
freq = sampleRate / 2;
@ -307,17 +275,25 @@ void CubicSDR::setSampleRate(long long rate_in) {
setFrequency(frequency);
}
void CubicSDR::setDevice(int deviceId) {
// SDRDeviceInfo *dev = (*getDevices())[deviceId];
// DeviceConfig *devConfig = config.getDevice(dev->getDeviceId());
void CubicSDR::setDevice(SDRDeviceInfo *dev) {
// sdrThread->setDevice(devConfig);
//
// setPPM(devConfig->getPPM());
// setDirectSampling(devConfig->getDirectSampling());
// setSwapIQ(devConfig->getIQSwap());
// setOffset(devConfig->getOffset());
if (!sdrThread->isTerminated()) {
sdrThread->terminate();
if (t_SDR) {
t_SDR->join();
}
}
sdrThread->setDevice(dev);
DeviceConfig *devConfig = config.getDevice(dev->getDeviceId());
setPPM(devConfig->getPPM());
setDirectSampling(devConfig->getDirectSampling());
setSwapIQ(devConfig->getIQSwap());
setOffset(devConfig->getOffset());
t_SDR = new std::thread(&SDRThread::threadMain, sdrThread);
}
SDRDeviceInfo *CubicSDR::getDevice() {

View File

@ -14,6 +14,7 @@
#include "SDRThread.h"
#else
#include "SoapySDRThread.h"
#include "SDREnumerator.h"
#endif
#include "SDRPostThread.h"
#include "AudioThread.h"
@ -42,9 +43,10 @@ public:
virtual void OnInitCmdLine(wxCmdLineParser& parser);
virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
SDRDeviceInfo *deviceSelector();
void deviceSelector();
void sdrThreadNotify(SDRThread::SDRThreadState state, std::string message);
void sdrEnumThreadNotify(SDREnumerator::SDREnumState state, std::string message);
void setFrequency(long long freq);
long long getFrequency();
@ -61,7 +63,7 @@ public:
long long getSampleRate();
std::vector<SDRDeviceInfo *> *getDevices();
void setDevice(int deviceId);
void setDevice(SDRDeviceInfo *dev);
SDRDeviceInfo * getDevice();
ScopeVisualProcessor *getScopeProcessor();
@ -104,6 +106,7 @@ private:
int directSamplingMode;
SDRThread *sdrThread;
SDREnumerator *sdrEnum;
SDRPostThread *sdrPostThread;
SpectrumVisualDataThread *spectrumVisualThread;
SpectrumVisualDataThread *demodVisualThread;
@ -120,10 +123,7 @@ private:
VisualDataReDistributor<DemodulatorThreadIQData> spectrumDistributor;
std::thread *t_SDR;
std::thread *t_PostSDR;
std::thread *t_SpectrumVisual;
std::thread *t_DemodVisual;
std::thread *t_SDR, *t_SDREnum, *t_PostSDR, *t_SpectrumVisual, *t_DemodVisual;
};
static const wxCmdLineEntryDesc commandLineInfo [] =

View File

@ -1,4 +1,40 @@
#include "SDRDevices.h"
#include "CubicSDR.h"
SDRDevicesDialog::SDRDevicesDialog( wxWindow* parent ): devFrame( parent ) {
wxTreeItemId devRoot = devTree->AddRoot("Devices");
wxTreeItemId localBranch = devTree->AppendItem(devRoot, "Local");
wxTreeItemId remoteBranch = devTree->AppendItem(devRoot, "Remote");
devs = SDREnumerator::enumerate_devices();
for (devs_i = devs->begin(); devs_i != devs->end(); devs_i++) {
devItems[devTree->AppendItem(localBranch, (*devs_i)->getName())] = (*devs_i);
}
devTree->ExpandAll();
}
void SDRDevicesDialog::OnDeleteItem( wxTreeEvent& event ) {
event.Skip();
}
void SDRDevicesDialog::OnSelectionChanged( wxTreeEvent& event ) {
event.Skip();
}
void SDRDevicesDialog::OnAddRemote( wxMouseEvent& event ) {
event.Skip();
}
void SDRDevicesDialog::OnUseSelected( wxMouseEvent& event ) {
wxTreeItemId selId = devTree->GetSelection();
devItems_i = devItems.find(selId);
if (devItems_i != devItems.end()) {
dev = devItems[selId];
wxGetApp().setDevice(dev);
Close();
}
}
#include "SDRDevicesForm.h"

File diff suppressed because it is too large Load Diff

View File

@ -1 +1,24 @@
#pragma once
#pragma once
#include "SDRDevices.h"
#include "SDRDevicesForm.h"
#include "SoapySDRThread.h"
#include "SDREnumerator.h"
class SDRDevicesDialog: public devFrame {
public:
SDRDevicesDialog( wxWindow* parent );
void OnDeleteItem( wxTreeEvent& event );
void OnSelectionChanged( wxTreeEvent& event );
void OnAddRemote( wxMouseEvent& event );
void OnUseSelected( wxMouseEvent& event );
private:
std::vector<SDRDeviceInfo *> *devs;
std::vector<SDRDeviceInfo *>::iterator devs_i;
std::map<wxTreeItemId, SDRDeviceInfo *> devItems;
std::map<wxTreeItemId, SDRDeviceInfo *>::iterator devItems_i;
SDRDeviceInfo *dev = NULL;
};

View File

@ -15,12 +15,42 @@ devFrame::devFrame( wxWindow* parent, wxWindowID id, const wxString& title, cons
devStatusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY );
wxBoxSizer* devFrameSizer;
devFrameSizer = new wxBoxSizer( wxHORIZONTAL );
devFrameSizer = new wxBoxSizer( wxVERTICAL );
devTree = new wxTreeCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE );
devFrameSizer->Add( devTree, 1, wxEXPAND, 5 );
m_panel3 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer4;
bSizer4 = new wxBoxSizer( wxHORIZONTAL );
devTabs = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_panel6 = new wxPanel( m_panel3, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer6;
bSizer6 = new wxBoxSizer( wxVERTICAL );
devTree = new wxTreeCtrl( m_panel6, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE );
bSizer6->Add( devTree, 1, wxEXPAND, 5 );
m_panel4 = new wxPanel( m_panel6, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer5;
bSizer5 = new wxBoxSizer( wxHORIZONTAL );
m_addRemoteButton = new wxButton( m_panel4, wxID_ANY, wxT("Add Remote"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer5->Add( m_addRemoteButton, 1, wxALL, 5 );
m_useSelectedButton = new wxButton( m_panel4, wxID_ANY, wxT("Use Selected"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer5->Add( m_useSelectedButton, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_panel4->SetSizer( bSizer5 );
m_panel4->Layout();
bSizer5->Fit( m_panel4 );
bSizer6->Add( m_panel4, 0, wxEXPAND, 5 );
m_panel6->SetSizer( bSizer6 );
m_panel6->Layout();
bSizer6->Fit( m_panel6 );
bSizer4->Add( m_panel6, 1, wxEXPAND | wxALL, 5 );
devTabs = new wxNotebook( m_panel3, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
devInfoPanel = new wxPanel( devTabs, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* devInfoSizer;
devInfoSizer = new wxBoxSizer( wxVERTICAL );
@ -46,24 +76,33 @@ devFrame::devFrame( wxWindow* parent, wxWindowID id, const wxString& title, cons
devParamsSizer->Fit( devParamsPanel );
devTabs->AddPage( devParamsPanel, wxT("Parameters"), false );
devFrameSizer->Add( devTabs, 2, wxEXPAND, 5 );
bSizer4->Add( devTabs, 1, wxEXPAND, 5 );
m_panel3->SetSizer( bSizer4 );
m_panel3->Layout();
bSizer4->Fit( m_panel3 );
devFrameSizer->Add( m_panel3, 1, wxEXPAND | wxALL, 5 );
this->SetSizer( devFrameSizer );
this->Layout();
devMenuBar = new wxMenuBar( 0 );
devFileMenu = new wxMenu();
devMenuBar->Append( devFileMenu, wxT("File") );
devEditMenu = new wxMenu();
devMenuBar->Append( devEditMenu, wxT("Edit") );
this->SetMenuBar( devMenuBar );
this->Centre( wxBOTH );
// Connect Events
devTree->Connect( wxEVT_COMMAND_TREE_DELETE_ITEM, wxTreeEventHandler( devFrame::OnDeleteItem ), NULL, this );
devTree->Connect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( devFrame::OnSelectionChanged ), NULL, this );
m_addRemoteButton->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( devFrame::OnAddRemote ), NULL, this );
m_useSelectedButton->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( devFrame::OnUseSelected ), NULL, this );
}
devFrame::~devFrame()
{
// Disconnect Events
devTree->Disconnect( wxEVT_COMMAND_TREE_DELETE_ITEM, wxTreeEventHandler( devFrame::OnDeleteItem ), NULL, this );
devTree->Disconnect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( devFrame::OnSelectionChanged ), NULL, this );
m_addRemoteButton->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( devFrame::OnAddRemote ), NULL, this );
m_useSelectedButton->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( devFrame::OnUseSelected ), NULL, this );
}

View File

@ -17,14 +17,14 @@
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/treectrl.h>
#include <wx/listctrl.h>
#include <wx/button.h>
#include <wx/sizer.h>
#include <wx/panel.h>
#include <wx/listctrl.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/notebook.h>
#include <wx/menu.h>
#include <wx/frame.h>
///////////////////////////////////////////////////////////////////////////
@ -39,15 +39,24 @@ class devFrame : public wxFrame
protected:
wxStatusBar* devStatusBar;
wxPanel* m_panel3;
wxPanel* m_panel6;
wxTreeCtrl* devTree;
wxPanel* m_panel4;
wxButton* m_addRemoteButton;
wxButton* m_useSelectedButton;
wxNotebook* devTabs;
wxPanel* devInfoPanel;
wxListCtrl* m_DevInfoList;
wxPanel* devParamsPanel;
wxListCtrl* m_ParamInfoList;
wxMenuBar* devMenuBar;
wxMenu* devFileMenu;
wxMenu* devEditMenu;
// Virtual event handlers, overide them in your derived class
virtual void OnDeleteItem( wxTreeEvent& event ) { event.Skip(); }
virtual void OnSelectionChanged( wxTreeEvent& event ) { event.Skip(); }
virtual void OnAddRemote( wxMouseEvent& event ) { event.Skip(); }
virtual void OnUseSelected( wxMouseEvent& event ) { event.Skip(); }
public:

158
src/sdr/SDREnumerator.cpp Normal file
View File

@ -0,0 +1,158 @@
#include "SDREnumerator.h"
#include "CubicSDRDefs.h"
#include <vector>
#include "CubicSDR.h"
#include <string>
std::vector<std::string> SDREnumerator::factories;
std::vector<std::string> SDREnumerator::modules;
std::vector<SDRDeviceInfo *> SDREnumerator::devs;
SDREnumerator::SDREnumerator() : IOThread() {
}
SDREnumerator::~SDREnumerator() {
}
std::vector<SDRDeviceInfo *> *SDREnumerator::enumerate_devices() {
if (SDREnumerator::devs.size()) {
return &SDREnumerator::devs;
}
std::cout << "SoapySDR init.." << std::endl;
std::cout << "\tAPI Version: v" << SoapySDR::getAPIVersion() << std::endl;
std::cout << "\tABI Version: v" << SoapySDR::getABIVersion() << std::endl;
std::cout << "\tInstall root: " << SoapySDR::getRootPath() << std::endl;
modules = SoapySDR::listModules();
for (size_t i = 0; i < modules.size(); i++) {
std::cout << "\tModule found: " << modules[i] << std::endl;
}
if (modules.empty()) {
std::cout << "No modules found!" << std::endl;
}
std::cout << "\tLoading modules... " << std::flush;
SoapySDR::loadModules();
std::cout << "done" << std::endl;
if (SDREnumerator::factories.size()) {
SDREnumerator::factories.erase(SDREnumerator::factories.begin(), SDREnumerator::factories.end());
}
std::cout << "\tAvailable factories...";
SoapySDR::FindFunctions factories = SoapySDR::Registry::listFindFunctions();
for (SoapySDR::FindFunctions::const_iterator it = factories.begin(); it != factories.end(); ++it) {
if (it != factories.begin()) {
std::cout << ", ";
}
std::cout << it->first;
SDREnumerator::factories.push_back(it->first);
}
if (factories.empty()) {
std::cout << "No factories found!" << std::endl;
}
std::cout << std::endl;
std::vector<SoapySDR::Kwargs> results = SoapySDR::Device::enumerate();
// Remote driver test..
/* * /
SDRDeviceInfo *remoteDev = new SDRDeviceInfo();
remoteDev->setDriver("remote");
remoteDev->setName("SoapySDR Remote Test");
SoapySDR::Kwargs remoteArgs;
remoteArgs["driver"] = "remote";
// remoteArgs["remote"] = "127.0.0.1";
remoteArgs["remote"] = "192.168.1.103";
remoteArgs["remote:driver"] = "rtlsdr";
remoteArgs["buffers"] = "6";
remoteArgs["buflen"] = "16384";
remoteDev->setDeviceArgs(remoteArgs);
SoapySDR::Kwargs streamArgs;
streamArgs["remote:mtu"] = "8192";
streamArgs["remote:format"] = "CS8";
streamArgs["remote:window"] = "16384000";
remoteDev->setStreamArgs(streamArgs);
SDRThread::devs.push_back(remoteDev);
// */
for (size_t i = 0; i < results.size(); i++) {
std::cout << "Found device " << i << std::endl;
SDRDeviceInfo *dev = new SDRDeviceInfo();
for (SoapySDR::Kwargs::const_iterator it = results[i].begin(); it != results[i].end(); ++it) {
std::cout << " " << it->first << " = " << it->second << std::endl;
if (it->first == "driver") {
dev->setDriver(it->second);
} else if (it->first == "label") {
dev->setName(it->second);
}
}
dev->setDeviceArgs(results[i]);
std::cout << "Make device " << i << std::endl;
try {
SoapySDR::Device *device = SoapySDR::Device::make(dev->getDeviceArgs());
SoapySDR::Kwargs info = device->getHardwareInfo();
for (SoapySDR::Kwargs::const_iterator it = info.begin(); it != info.end(); ++it) {
std::cout << " " << it->first << "=" << it->second << std::endl;
if (it->first == "hardware") {
dev->setHardware(it->second);
}
}
if (device->hasDCOffsetMode(SOAPY_SDR_RX, 0)) {
device->setDCOffsetMode(SOAPY_SDR_RX, 0, true);
std::cout << "Hardware DC offset support detected; internal DC offset correction will be disabled." << std::endl;
dev->setHardwareDC(true);
} else {
dev->setHardwareDC(false);
}
SoapySDR::Device::unmake(device);
dev->setAvailable(true);
} catch (const std::exception &ex) {
std::cerr << "Error making device: " << ex.what() << std::endl;
dev->setAvailable(false);
}
std::cout << std::endl;
SDREnumerator::devs.push_back(dev);
}
if (results.empty()) {
std::cout << "No devices found!" << std::endl;
}
std::cout << std::endl;
return &SDREnumerator::devs;
}
void SDREnumerator::run() {
std::cout << "SDR enumerator starting." << std::endl;
terminated.store(false);
std::cout << "Enumerator devices." << std::endl;
SDREnumerator::enumerate_devices();
std::cout << "Reporting enumeration complete." << std::endl;
terminated.store(true);
wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_DEVICES_READY, "Devices Ready.");
std::cout << "SDR enumerator done." << std::endl;
}

31
src/sdr/SDREnumerator.h Normal file
View File

@ -0,0 +1,31 @@
#pragma once
#include <atomic>
#include "ThreadQueue.h"
#include "IOThread.h"
#include "SDRDeviceInfo.h"
#include "AppConfig.h"
#include <SoapySDR/Version.hpp>
#include <SoapySDR/Modules.hpp>
#include <SoapySDR/Registry.hpp>
#include <SoapySDR/Device.hpp>
class SDREnumerator: public IOThread {
private:
public:
SDREnumerator();
~SDREnumerator();
enum SDREnumState { SDR_ENUM_DEVICES_READY, SDR_ENUM_TERMINATED, SDR_ENUM_FAILED };
static std::vector<SDRDeviceInfo *> *enumerate_devices();
void run();
protected:
static std::vector<std::string> factories;
static std::vector<std::string> modules;
static std::vector<SDRDeviceInfo *> devs;
};

View File

@ -5,11 +5,6 @@
#include <string>
std::vector<std::string> SDRThread::factories;
std::vector<std::string> SDRThread::modules;
std::vector<SDRDeviceInfo *> SDRThread::devs;
SDRThread::SDRThread() : IOThread() {
device = NULL;
@ -39,126 +34,6 @@ SDRThread::~SDRThread() {
}
std::vector<SDRDeviceInfo *> *SDRThread::enumerate_devices() {
if (SDRThread::devs.size()) {
return &SDRThread::devs;
}
std::cout << "SoapySDR init.." << std::endl;
std::cout << "\tAPI Version: v" << SoapySDR::getAPIVersion() << std::endl;
std::cout << "\tABI Version: v" << SoapySDR::getABIVersion() << std::endl;
std::cout << "\tInstall root: " << SoapySDR::getRootPath() << std::endl;
modules = SoapySDR::listModules();
for (size_t i = 0; i < modules.size(); i++) {
std::cout << "\tModule found: " << modules[i] << std::endl;
}
if (modules.empty()) {
std::cout << "No modules found!" << std::endl;
}
std::cout << "\tLoading modules... " << std::flush;
SoapySDR::loadModules();
std::cout << "done" << std::endl;
if (SDRThread::factories.size()) {
SDRThread::factories.erase(SDRThread::factories.begin(), SDRThread::factories.end());
}
std::cout << "\tAvailable factories...";
SoapySDR::FindFunctions factories = SoapySDR::Registry::listFindFunctions();
for (SoapySDR::FindFunctions::const_iterator it = factories.begin(); it != factories.end(); ++it) {
if (it != factories.begin()) {
std::cout << ", ";
}
std::cout << it->first;
SDRThread::factories.push_back(it->first);
}
if (factories.empty()) {
std::cout << "No factories found!" << std::endl;
}
std::cout << std::endl;
std::vector<SoapySDR::Kwargs> results = SoapySDR::Device::enumerate();
// Remote driver test..
/* * /
SDRDeviceInfo *remoteDev = new SDRDeviceInfo();
remoteDev->setDriver("remote");
remoteDev->setName("SoapySDR Remote Test");
SoapySDR::Kwargs remoteArgs;
remoteArgs["driver"] = "remote";
// remoteArgs["remote"] = "127.0.0.1";
remoteArgs["remote"] = "192.168.1.103";
remoteArgs["remote:driver"] = "rtlsdr";
remoteArgs["buffers"] = "6";
remoteArgs["buflen"] = "16384";
remoteDev->setDeviceArgs(remoteArgs);
SoapySDR::Kwargs streamArgs;
streamArgs["remote:mtu"] = "8192";
streamArgs["remote:format"] = "CS8";
streamArgs["remote:window"] = "16384000";
remoteDev->setStreamArgs(streamArgs);
SDRThread::devs.push_back(remoteDev);
// */
for (size_t i = 0; i < results.size(); i++) {
std::cout << "Found device " << i << std::endl;
SDRDeviceInfo *dev = new SDRDeviceInfo();
for (SoapySDR::Kwargs::const_iterator it = results[i].begin(); it != results[i].end(); ++it) {
std::cout << " " << it->first << " = " << it->second << std::endl;
if (it->first == "driver") {
dev->setDriver(it->second);
} else if (it->first == "label") {
dev->setName(it->second);
}
}
dev->setDeviceArgs(results[i]);
std::cout << "Make device " << i << std::endl;
try {
SoapySDR::Device *device = SoapySDR::Device::make(dev->getDeviceArgs());
SoapySDR::Kwargs info = device->getHardwareInfo();
for (SoapySDR::Kwargs::const_iterator it = info.begin(); it != info.end(); ++it) {
std::cout << " " << it->first << "=" << it->second << std::endl;
if (it->first == "hardware") {
dev->setHardware(it->second);
}
}
if (device->hasDCOffsetMode(SOAPY_SDR_RX, 0)) {
device->setDCOffsetMode(SOAPY_SDR_RX, 0, true);
std::cout << "Hardware DC offset support detected; internal DC offset correction will be disabled." << std::endl;
dev->setHardwareDC(true);
} else {
dev->setHardwareDC(false);
}
SoapySDR::Device::unmake(device);
dev->setAvailable(true);
} catch (const std::exception &ex) {
std::cerr << "Error making device: " << ex.what() << std::endl;
dev->setAvailable(false);
}
std::cout << std::endl;
SDRThread::devs.push_back(dev);
}
if (results.empty()) {
std::cout << "No devices found!" << std::endl;
}
std::cout << std::endl;
return &SDRThread::devs;
}
void SDRThread::init() {
SDRDeviceInfo *devInfo = deviceInfo.load();
deviceConfig.store(wxGetApp().getConfig()->getDevice(devInfo->getDeviceId()));
@ -303,12 +178,7 @@ void SDRThread::run() {
deinit();
std::cout << "device deinit()" << std::endl;
} else {
std::cout << "Device setting not found, enumerating." << std::endl;
SDRThread::enumerate_devices();
std::cout << "Reporting enumeration complete." << std::endl;
wxGetApp().sdrThreadNotify(SDRThread::SDR_THREAD_DEVICES_READY, "Devices Ready.");
terminated.store(true);
return;
std::cout << "SDR Thread started with null device?" << std::endl;
}
std::cout << "SDR thread done." << std::endl;

View File

@ -47,10 +47,8 @@ private:
public:
SDRThread();
~SDRThread();
enum SDRThreadState { SDR_THREAD_DEVICES_READY, SDR_THREAD_NO_DEVICES, SDR_THREAD_TERMINATED, SDR_THREAD_FAILED };
enum SDRThreadState { SDR_THREAD_TERMINATED, SDR_THREAD_FAILED };
static std::vector<SDRDeviceInfo *> *enumerate_devices();
void run();
SDRDeviceInfo *getDevice();
@ -73,9 +71,6 @@ public:
int getDirectSampling();
protected:
static std::vector<std::string> factories;
static std::vector<std::string> modules;
static std::vector<SDRDeviceInfo *> devs;
SoapySDR::Stream *stream;
SoapySDR::Device *device;
void *buffs[1];