mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2025-02-03 09:44:26 -05:00
Make init asynchronous, support for SoapyRemote servers
- tested with 2xRTLSDR, SDRPlay + RTLSDR on Raspberry Pi - parameters/info dialog portion currently hidden until it works - remotes aren’t saved on exit yet - can now start CubicSDR without devices (remote only mode) - can’t currently refresh local or remote devices through UI - can’t currently remove remotes through UI
This commit is contained in:
parent
3bf0439c56
commit
0df2439658
113
src/CubicSDR.cpp
113
src/CubicSDR.cpp
@ -18,8 +18,6 @@
|
|||||||
#include "CoreFoundation/CoreFoundation.h"
|
#include "CoreFoundation/CoreFoundation.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <SDRDevices.h>
|
|
||||||
|
|
||||||
IMPLEMENT_APP(CubicSDR)
|
IMPLEMENT_APP(CubicSDR)
|
||||||
|
|
||||||
CubicSDR::CubicSDR() : appframe(NULL), m_glContext(NULL), frequency(0), offset(0), ppm(0), snap(1), sampleRate(DEFAULT_SAMPLE_RATE), directSamplingMode(0),
|
CubicSDR::CubicSDR() : appframe(NULL), m_glContext(NULL), frequency(0), offset(0), ppm(0), snap(1), sampleRate(DEFAULT_SAMPLE_RATE), directSamplingMode(0),
|
||||||
@ -51,6 +49,8 @@ bool CubicSDR::OnInit() {
|
|||||||
offset = 0;
|
offset = 0;
|
||||||
ppm = 0;
|
ppm = 0;
|
||||||
directSamplingMode = 0;
|
directSamplingMode = 0;
|
||||||
|
devicesReady.store(false);
|
||||||
|
deviceSelectorOpen.store(false);
|
||||||
|
|
||||||
// Visual Data
|
// Visual Data
|
||||||
spectrumVisualThread = new SpectrumVisualDataThread();
|
spectrumVisualThread = new SpectrumVisualDataThread();
|
||||||
@ -99,21 +99,24 @@ bool CubicSDR::OnInit() {
|
|||||||
t_DemodVisual = new std::thread(&SpectrumVisualDataThread::threadMain, demodVisualThread);
|
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();
|
sdrEnum = new SDREnumerator();
|
||||||
t_SDREnum = new std::thread(&SDREnumerator::threadMain, sdrEnum);
|
|
||||||
|
|
||||||
appframe = new AppFrame();
|
appframe = new AppFrame();
|
||||||
|
deviceSelectorOpen.store(true);
|
||||||
|
deviceSelectorDialog = new SDRDevicesDialog(appframe);
|
||||||
|
deviceSelectorDialog->Show();
|
||||||
|
|
||||||
#ifdef __APPLE__
|
t_SDREnum = new std::thread(&SDREnumerator::threadMain, sdrEnum);
|
||||||
int main_policy;
|
|
||||||
struct sched_param main_param;
|
|
||||||
|
|
||||||
main_policy = SCHED_RR;
|
//#ifdef __APPLE__
|
||||||
main_param.sched_priority = sched_get_priority_min(SCHED_RR)+2;
|
// int main_policy;
|
||||||
|
// struct sched_param main_param;
|
||||||
pthread_setschedparam(pthread_self(), main_policy, &main_param);
|
//
|
||||||
#endif
|
// main_policy = SCHED_RR;
|
||||||
|
// main_param.sched_priority = sched_get_priority_min(SCHED_RR)+2;
|
||||||
|
//
|
||||||
|
// pthread_setschedparam(pthread_self(), main_policy, &main_param);
|
||||||
|
//#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -191,36 +194,61 @@ bool CubicSDR::OnCmdLineParsed(wxCmdLineParser& parser) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CubicSDR::deviceSelector() {
|
void CubicSDR::deviceSelector() {
|
||||||
if (sdrEnum->isTerminated()) {
|
if (deviceSelectorOpen) {
|
||||||
devs = SDREnumerator::enumerate_devices();
|
deviceSelectorDialog->Raise();
|
||||||
SDRDevicesDialog *dlg = new SDRDevicesDialog(appframe);
|
deviceSelectorDialog->SetFocus();
|
||||||
dlg->Show();
|
return;
|
||||||
}
|
}
|
||||||
|
deviceSelectorOpen = true;
|
||||||
|
deviceSelectorDialog = new SDRDevicesDialog(appframe);
|
||||||
|
deviceSelectorDialog->Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CubicSDR::addRemote(std::string remoteAddr) {
|
||||||
|
SDREnumerator::addRemote(remoteAddr);
|
||||||
|
devicesReady.store(false);
|
||||||
|
t_SDREnum = new std::thread(&SDREnumerator::threadMain, sdrEnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CubicSDR::removeRemote(std::string remoteAddr) {
|
||||||
|
SDREnumerator::removeRemote(remoteAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubicSDR::sdrThreadNotify(SDRThread::SDRThreadState state, std::string message) {
|
void CubicSDR::sdrThreadNotify(SDRThread::SDRThreadState state, std::string message) {
|
||||||
|
notify_busy.lock();
|
||||||
|
if (state == SDRThread::SDR_THREAD_MESSAGE) {
|
||||||
|
notifyMessage = message;
|
||||||
|
}
|
||||||
if (state == SDRThread::SDR_THREAD_TERMINATED) {
|
if (state == SDRThread::SDR_THREAD_TERMINATED) {
|
||||||
t_SDR->join();
|
t_SDR->join();
|
||||||
delete t_SDR;
|
delete t_SDR;
|
||||||
}
|
}
|
||||||
if (state == SDRThread::SDR_THREAD_FAILED) {
|
if (state == SDRThread::SDR_THREAD_FAILED) {
|
||||||
wxMessageDialog *info;
|
notifyMessage = message;
|
||||||
info = new wxMessageDialog(NULL, message, wxT("Error initializing device"), wxOK | wxICON_ERROR);
|
// wxMessageDialog *info;
|
||||||
info->ShowModal();
|
// info = new wxMessageDialog(NULL, message, wxT("Error initializing device"), wxOK | wxICON_ERROR);
|
||||||
|
// info->ShowModal();
|
||||||
}
|
}
|
||||||
|
appframe->SetStatusText(message);
|
||||||
|
notify_busy.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CubicSDR::sdrEnumThreadNotify(SDREnumerator::SDREnumState state, std::string message) {
|
void CubicSDR::sdrEnumThreadNotify(SDREnumerator::SDREnumState state, std::string message) {
|
||||||
|
notify_busy.lock();
|
||||||
|
if (state == SDREnumerator::SDR_ENUM_MESSAGE) {
|
||||||
|
notifyMessage = message;
|
||||||
|
}
|
||||||
if (state == SDREnumerator::SDR_ENUM_DEVICES_READY) {
|
if (state == SDREnumerator::SDR_ENUM_DEVICES_READY) {
|
||||||
deviceSelector();
|
devs = SDREnumerator::enumerate_devices("", true);
|
||||||
|
devicesReady.store(true);
|
||||||
}
|
}
|
||||||
if (state == SDREnumerator::SDR_ENUM_FAILED) {
|
if (state == SDREnumerator::SDR_ENUM_FAILED) {
|
||||||
|
notifyMessage = message;
|
||||||
sdrEnum->terminate();
|
sdrEnum->terminate();
|
||||||
wxMessageDialog *info;
|
|
||||||
info = new wxMessageDialog(NULL, message, wxT("Error enumerating devices"), wxOK | wxICON_ERROR);
|
|
||||||
info->ShowModal();
|
|
||||||
}
|
}
|
||||||
|
appframe->SetStatusText(message);
|
||||||
|
notify_busy.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -296,11 +324,13 @@ void CubicSDR::setDevice(SDRDeviceInfo *dev) {
|
|||||||
freqHigh = chan->getRFRange().getHigh();
|
freqHigh = chan->getRFRange().getHigh();
|
||||||
freqLow = chan->getRFRange().getLow();
|
freqLow = chan->getRFRange().getLow();
|
||||||
|
|
||||||
if (frequency > freqHigh) {
|
// upconverter settings don't like this, need to handle elsewhere..
|
||||||
frequency = freqHigh;
|
// if (frequency > freqHigh) {
|
||||||
} else if (frequency < freqLow) {
|
// frequency = freqHigh;
|
||||||
frequency = freqLow;
|
// }
|
||||||
}
|
// else if (frequency < freqLow) {
|
||||||
|
// frequency = freqLow;
|
||||||
|
// }
|
||||||
|
|
||||||
int rateHigh, rateLow;
|
int rateHigh, rateLow;
|
||||||
rateLow = chan->getSampleRates()[0];
|
rateLow = chan->getSampleRates()[0];
|
||||||
@ -344,7 +374,7 @@ SpectrumVisualProcessor *CubicSDR::getDemodSpectrumProcessor() {
|
|||||||
return demodVisualThread->getProcessor();
|
return demodVisualThread->getProcessor();
|
||||||
}
|
}
|
||||||
|
|
||||||
VisualDataReDistributor<DemodulatorThreadIQData> *CubicSDR::getSpectrumDistributor() {
|
VisualDataDistributor<DemodulatorThreadIQData> *CubicSDR::getSpectrumDistributor() {
|
||||||
return &spectrumDistributor;
|
return &spectrumDistributor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,8 +424,7 @@ AppConfig *CubicSDR::getConfig() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CubicSDR::saveConfig() {
|
void CubicSDR::saveConfig() {
|
||||||
#warning Configuration Save Disabled
|
config.save();
|
||||||
// config.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubicSDR::setPPM(int ppm_in) {
|
void CubicSDR::setPPM(int ppm_in) {
|
||||||
@ -453,3 +482,23 @@ void CubicSDR::setFrequencySnap(int snap) {
|
|||||||
int CubicSDR::getFrequencySnap() {
|
int CubicSDR::getFrequencySnap() {
|
||||||
return snap;
|
return snap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CubicSDR::areDevicesReady() {
|
||||||
|
return devicesReady.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CubicSDR::areDevicesEnumerating() {
|
||||||
|
return !sdrEnum->isTerminated();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CubicSDR::getNotification() {
|
||||||
|
std::string msg;
|
||||||
|
notify_busy.lock();
|
||||||
|
msg = notifyMessage;
|
||||||
|
notify_busy.unlock();
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CubicSDR::setDeviceSelectorClosed() {
|
||||||
|
deviceSelectorOpen.store(false);
|
||||||
|
}
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "ScopeVisualProcessor.h"
|
#include "ScopeVisualProcessor.h"
|
||||||
#include "SpectrumVisualProcessor.h"
|
#include "SpectrumVisualProcessor.h"
|
||||||
#include "SpectrumVisualDataThread.h"
|
#include "SpectrumVisualDataThread.h"
|
||||||
|
#include "SDRDevices.h"
|
||||||
|
|
||||||
#include <wx/cmdline.h>
|
#include <wx/cmdline.h>
|
||||||
|
|
||||||
@ -69,7 +70,7 @@ public:
|
|||||||
ScopeVisualProcessor *getScopeProcessor();
|
ScopeVisualProcessor *getScopeProcessor();
|
||||||
SpectrumVisualProcessor *getSpectrumProcessor();
|
SpectrumVisualProcessor *getSpectrumProcessor();
|
||||||
SpectrumVisualProcessor *getDemodSpectrumProcessor();
|
SpectrumVisualProcessor *getDemodSpectrumProcessor();
|
||||||
VisualDataReDistributor<DemodulatorThreadIQData> *getSpectrumDistributor();
|
VisualDataDistributor<DemodulatorThreadIQData> *getSpectrumDistributor();
|
||||||
|
|
||||||
DemodulatorThreadOutputQueue* getAudioVisualQueue();
|
DemodulatorThreadOutputQueue* getAudioVisualQueue();
|
||||||
DemodulatorThreadInputQueue* getIQVisualQueue();
|
DemodulatorThreadInputQueue* getIQVisualQueue();
|
||||||
@ -91,6 +92,15 @@ public:
|
|||||||
void showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetMode = FrequencyDialog::FDIALOG_TARGET_DEFAULT);
|
void showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetMode = FrequencyDialog::FDIALOG_TARGET_DEFAULT);
|
||||||
AppFrame *getAppFrame();
|
AppFrame *getAppFrame();
|
||||||
|
|
||||||
|
bool areDevicesReady();
|
||||||
|
bool areDevicesEnumerating();
|
||||||
|
std::string getNotification();
|
||||||
|
|
||||||
|
void addRemote(std::string remoteAddr);
|
||||||
|
void removeRemote(std::string remoteAddr);
|
||||||
|
|
||||||
|
void setDeviceSelectorClosed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AppFrame *appframe;
|
AppFrame *appframe;
|
||||||
AppConfig config;
|
AppConfig config;
|
||||||
@ -121,9 +131,15 @@ private:
|
|||||||
|
|
||||||
ScopeVisualProcessor scopeProcessor;
|
ScopeVisualProcessor scopeProcessor;
|
||||||
|
|
||||||
VisualDataReDistributor<DemodulatorThreadIQData> spectrumDistributor;
|
VisualDataDistributor<DemodulatorThreadIQData> spectrumDistributor;
|
||||||
|
|
||||||
|
SDRDevicesDialog *deviceSelectorDialog;
|
||||||
|
|
||||||
std::thread *t_SDR, *t_SDREnum, *t_PostSDR, *t_SpectrumVisual, *t_DemodVisual;
|
std::thread *t_SDR, *t_SDREnum, *t_PostSDR, *t_SpectrumVisual, *t_DemodVisual;
|
||||||
|
std::atomic_bool devicesReady;
|
||||||
|
std::atomic_bool deviceSelectorOpen;
|
||||||
|
std::string notifyMessage;
|
||||||
|
std::mutex notify_busy;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const wxCmdLineEntryDesc commandLineInfo [] =
|
static const wxCmdLineEntryDesc commandLineInfo [] =
|
||||||
|
@ -1,19 +1,21 @@
|
|||||||
#include "SDRDevices.h"
|
#include "SDRDevices.h"
|
||||||
|
|
||||||
|
#include <wx/textdlg.h>
|
||||||
|
#include <wx/msgdlg.h>
|
||||||
|
|
||||||
#include "CubicSDR.h"
|
#include "CubicSDR.h"
|
||||||
|
|
||||||
SDRDevicesDialog::SDRDevicesDialog( wxWindow* parent ): devFrame( parent ) {
|
SDRDevicesDialog::SDRDevicesDialog( wxWindow* parent ): devFrame( parent ) {
|
||||||
wxTreeItemId devRoot = devTree->AddRoot("Devices");
|
refresh = true;
|
||||||
wxTreeItemId localBranch = devTree->AppendItem(devRoot, "Local");
|
m_addRemoteButton->Disable();
|
||||||
wxTreeItemId remoteBranch = devTree->AppendItem(devRoot, "Remote");
|
m_useSelectedButton->Disable();
|
||||||
|
m_deviceTimer.Start(250);
|
||||||
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::OnClose( wxCloseEvent& event ) {
|
||||||
|
wxGetApp().setDeviceSelectorClosed();
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
void SDRDevicesDialog::OnDeleteItem( wxTreeEvent& event ) {
|
void SDRDevicesDialog::OnDeleteItem( wxTreeEvent& event ) {
|
||||||
event.Skip();
|
event.Skip();
|
||||||
@ -24,7 +26,24 @@ void SDRDevicesDialog::OnSelectionChanged( wxTreeEvent& event ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SDRDevicesDialog::OnAddRemote( wxMouseEvent& event ) {
|
void SDRDevicesDialog::OnAddRemote( wxMouseEvent& event ) {
|
||||||
event.Skip();
|
if (!SDREnumerator::hasRemoteModule()) {
|
||||||
|
wxMessageDialog *info;
|
||||||
|
info = new wxMessageDialog(NULL, wxT("Install SoapyRemote module to add remote servers.\n\nhttps://github.com/pothosware/SoapyRemote"), wxT("SoapyRemote not found."), wxOK | wxICON_ERROR);
|
||||||
|
info->ShowModal();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString remoteAddr =
|
||||||
|
wxGetTextFromUser("Remote Address (address[:port])\n\ni.e. 'raspberrypi.local', '192.168.1.103:1234'\n","SoapySDR Remote Address", "", this);
|
||||||
|
|
||||||
|
if (!remoteAddr.Trim().empty()) {
|
||||||
|
wxGetApp().addRemote(remoteAddr.Trim().ToStdString());
|
||||||
|
}
|
||||||
|
devTree->Disable();
|
||||||
|
m_addRemoteButton->Disable();
|
||||||
|
m_useSelectedButton->Disable();
|
||||||
|
refresh = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDRDevicesDialog::OnUseSelected( wxMouseEvent& event ) {
|
void SDRDevicesDialog::OnUseSelected( wxMouseEvent& event ) {
|
||||||
@ -38,3 +57,58 @@ void SDRDevicesDialog::OnUseSelected( wxMouseEvent& event ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SDRDevicesDialog::OnTreeDoubleClick( wxMouseEvent& event ) {
|
||||||
|
OnUseSelected(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRDevicesDialog::OnDeviceTimer( wxTimerEvent& event ) {
|
||||||
|
if (refresh) {
|
||||||
|
if (wxGetApp().areDevicesEnumerating() || !wxGetApp().areDevicesReady()) {
|
||||||
|
std::string msg = wxGetApp().getNotification();
|
||||||
|
devStatusBar->SetStatusText(msg);
|
||||||
|
devTree->DeleteAllItems();
|
||||||
|
devTree->AddRoot(msg);
|
||||||
|
event.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
devTree->DeleteAllItems();
|
||||||
|
|
||||||
|
wxTreeItemId devRoot = devTree->AddRoot("Devices");
|
||||||
|
wxTreeItemId localBranch = devTree->AppendItem(devRoot, "Local");
|
||||||
|
wxTreeItemId remoteBranch = devTree->AppendItem(devRoot, "Remote");
|
||||||
|
|
||||||
|
devs[""] = SDREnumerator::enumerate_devices("",true);
|
||||||
|
if (devs[""] != NULL) {
|
||||||
|
for (devs_i = devs[""]->begin(); devs_i != devs[""]->end(); devs_i++) {
|
||||||
|
devItems[devTree->AppendItem(localBranch, (*devs_i)->getName())] = (*devs_i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> remotes = SDREnumerator::getRemotes();
|
||||||
|
std::vector<std::string>::iterator remotes_i;
|
||||||
|
std::vector<SDRDeviceInfo *>::iterator remoteDevs_i;
|
||||||
|
|
||||||
|
if (remotes.size()) {
|
||||||
|
for (remotes_i = remotes.begin(); remotes_i != remotes.end(); remotes_i++) {
|
||||||
|
devs[*remotes_i] = SDREnumerator::enumerate_devices(*remotes_i, true);
|
||||||
|
wxTreeItemId remoteNode = devTree->AppendItem(remoteBranch, *remotes_i);
|
||||||
|
|
||||||
|
if (devs[*remotes_i] != NULL) {
|
||||||
|
for (remoteDevs_i = devs[*remotes_i]->begin(); remoteDevs_i != devs[*remotes_i]->end(); remoteDevs_i++) {
|
||||||
|
devItems[devTree->AppendItem(remoteNode, (*remoteDevs_i)->getName())] = (*remoteDevs_i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_addRemoteButton->Enable();
|
||||||
|
m_useSelectedButton->Enable();
|
||||||
|
devTree->Enable();
|
||||||
|
devTree->ExpandAll();
|
||||||
|
|
||||||
|
devStatusBar->SetStatusText("Ready.");
|
||||||
|
|
||||||
|
refresh = false;
|
||||||
|
}
|
||||||
|
}
|
@ -44,7 +44,7 @@
|
|||||||
<property name="minimum_size"></property>
|
<property name="minimum_size"></property>
|
||||||
<property name="name">devFrame</property>
|
<property name="name">devFrame</property>
|
||||||
<property name="pos"></property>
|
<property name="pos"></property>
|
||||||
<property name="size">692,467</property>
|
<property name="size">392,467</property>
|
||||||
<property name="style">wxDEFAULT_FRAME_STYLE</property>
|
<property name="style">wxDEFAULT_FRAME_STYLE</property>
|
||||||
<property name="subclass"></property>
|
<property name="subclass"></property>
|
||||||
<property name="title">CubicSDR :: SDR Devices</property>
|
<property name="title">CubicSDR :: SDR Devices</property>
|
||||||
@ -62,7 +62,7 @@
|
|||||||
<event name="OnAuiPaneRestore"></event>
|
<event name="OnAuiPaneRestore"></event>
|
||||||
<event name="OnAuiRender"></event>
|
<event name="OnAuiRender"></event>
|
||||||
<event name="OnChar"></event>
|
<event name="OnChar"></event>
|
||||||
<event name="OnClose"></event>
|
<event name="OnClose">OnClose</event>
|
||||||
<event name="OnEnterWindow"></event>
|
<event name="OnEnterWindow"></event>
|
||||||
<event name="OnEraseBackground"></event>
|
<event name="OnEraseBackground"></event>
|
||||||
<event name="OnHibernate"></event>
|
<event name="OnHibernate"></event>
|
||||||
@ -307,7 +307,7 @@
|
|||||||
<property name="permission">none</property>
|
<property name="permission">none</property>
|
||||||
<object class="sizeritem" expanded="0">
|
<object class="sizeritem" expanded="0">
|
||||||
<property name="border">5</property>
|
<property name="border">5</property>
|
||||||
<property name="flag">wxEXPAND</property>
|
<property name="flag">wxEXPAND|wxALIGN_RIGHT</property>
|
||||||
<property name="proportion">1</property>
|
<property name="proportion">1</property>
|
||||||
<object class="wxTreeCtrl" expanded="0">
|
<object class="wxTreeCtrl" expanded="0">
|
||||||
<property name="BottomDockable">1</property>
|
<property name="BottomDockable">1</property>
|
||||||
@ -330,7 +330,7 @@
|
|||||||
<property name="dock">Dock</property>
|
<property name="dock">Dock</property>
|
||||||
<property name="dock_fixed">0</property>
|
<property name="dock_fixed">0</property>
|
||||||
<property name="docking">Left</property>
|
<property name="docking">Left</property>
|
||||||
<property name="enabled">1</property>
|
<property name="enabled">0</property>
|
||||||
<property name="fg"></property>
|
<property name="fg"></property>
|
||||||
<property name="floatable">1</property>
|
<property name="floatable">1</property>
|
||||||
<property name="font"></property>
|
<property name="font"></property>
|
||||||
@ -368,7 +368,7 @@
|
|||||||
<event name="OnKeyUp"></event>
|
<event name="OnKeyUp"></event>
|
||||||
<event name="OnKillFocus"></event>
|
<event name="OnKillFocus"></event>
|
||||||
<event name="OnLeaveWindow"></event>
|
<event name="OnLeaveWindow"></event>
|
||||||
<event name="OnLeftDClick"></event>
|
<event name="OnLeftDClick">OnTreeDoubleClick</event>
|
||||||
<event name="OnLeftDown"></event>
|
<event name="OnLeftDown"></event>
|
||||||
<event name="OnLeftUp"></event>
|
<event name="OnLeftUp"></event>
|
||||||
<event name="OnMiddleDClick"></event>
|
<event name="OnMiddleDClick"></event>
|
||||||
@ -703,7 +703,7 @@
|
|||||||
<property name="floatable">0</property>
|
<property name="floatable">0</property>
|
||||||
<property name="font"></property>
|
<property name="font"></property>
|
||||||
<property name="gripper">0</property>
|
<property name="gripper">0</property>
|
||||||
<property name="hidden">0</property>
|
<property name="hidden">1</property>
|
||||||
<property name="id">wxID_ANY</property>
|
<property name="id">wxID_ANY</property>
|
||||||
<property name="max_size"></property>
|
<property name="max_size"></property>
|
||||||
<property name="maximize_button">0</property>
|
<property name="maximize_button">0</property>
|
||||||
@ -1142,6 +1142,15 @@
|
|||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="wxTimer" expanded="1">
|
||||||
|
<property name="enabled">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="name">m_deviceTimer</property>
|
||||||
|
<property name="oneshot">0</property>
|
||||||
|
<property name="period">5000</property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<event name="OnTimer">OnDeviceTimer</event>
|
||||||
|
</object>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
</wxFormBuilder_Project>
|
</wxFormBuilder_Project>
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "SDRDevices.h"
|
#include "SDRDevices.h"
|
||||||
#include "SDRDevicesForm.h"
|
#include "SDRDevicesForm.h"
|
||||||
@ -10,13 +12,17 @@ class SDRDevicesDialog: public devFrame {
|
|||||||
public:
|
public:
|
||||||
SDRDevicesDialog( wxWindow* parent );
|
SDRDevicesDialog( wxWindow* parent );
|
||||||
|
|
||||||
|
void OnClose( wxCloseEvent& event );
|
||||||
void OnDeleteItem( wxTreeEvent& event );
|
void OnDeleteItem( wxTreeEvent& event );
|
||||||
void OnSelectionChanged( wxTreeEvent& event );
|
void OnSelectionChanged( wxTreeEvent& event );
|
||||||
void OnAddRemote( wxMouseEvent& event );
|
void OnAddRemote( wxMouseEvent& event );
|
||||||
void OnUseSelected( wxMouseEvent& event );
|
void OnUseSelected( wxMouseEvent& event );
|
||||||
|
void OnTreeDoubleClick( wxMouseEvent& event );
|
||||||
|
void OnDeviceTimer( wxTimerEvent& event );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<SDRDeviceInfo *> *devs;
|
bool refresh;
|
||||||
|
std::map<std::string, std::vector<SDRDeviceInfo *>* > devs;
|
||||||
std::vector<SDRDeviceInfo *>::iterator devs_i;
|
std::vector<SDRDeviceInfo *>::iterator devs_i;
|
||||||
std::map<wxTreeItemId, SDRDeviceInfo *> devItems;
|
std::map<wxTreeItemId, SDRDeviceInfo *> devItems;
|
||||||
std::map<wxTreeItemId, SDRDeviceInfo *>::iterator devItems_i;
|
std::map<wxTreeItemId, SDRDeviceInfo *>::iterator devItems_i;
|
||||||
|
@ -26,7 +26,9 @@ devFrame::devFrame( wxWindow* parent, wxWindowID id, const wxString& title, cons
|
|||||||
bSizer6 = new wxBoxSizer( wxVERTICAL );
|
bSizer6 = new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
devTree = new wxTreeCtrl( m_panel6, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE );
|
devTree = new wxTreeCtrl( m_panel6, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE );
|
||||||
bSizer6->Add( devTree, 1, wxEXPAND, 5 );
|
devTree->Enable( false );
|
||||||
|
|
||||||
|
bSizer6->Add( devTree, 1, wxEXPAND|wxALIGN_RIGHT, 5 );
|
||||||
|
|
||||||
m_panel4 = new wxPanel( m_panel6, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
m_panel4 = new wxPanel( m_panel6, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||||
wxBoxSizer* bSizer5;
|
wxBoxSizer* bSizer5;
|
||||||
@ -51,6 +53,8 @@ devFrame::devFrame( wxWindow* parent, wxWindowID id, const wxString& title, cons
|
|||||||
bSizer4->Add( m_panel6, 1, wxEXPAND | wxALL, 5 );
|
bSizer4->Add( m_panel6, 1, wxEXPAND | wxALL, 5 );
|
||||||
|
|
||||||
devTabs = new wxNotebook( m_panel3, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
|
devTabs = new wxNotebook( m_panel3, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
devTabs->Hide();
|
||||||
|
|
||||||
devInfoPanel = new wxPanel( devTabs, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
devInfoPanel = new wxPanel( devTabs, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||||
wxBoxSizer* devInfoSizer;
|
wxBoxSizer* devInfoSizer;
|
||||||
devInfoSizer = new wxBoxSizer( wxVERTICAL );
|
devInfoSizer = new wxBoxSizer( wxVERTICAL );
|
||||||
@ -87,22 +91,29 @@ devFrame::devFrame( wxWindow* parent, wxWindowID id, const wxString& title, cons
|
|||||||
|
|
||||||
this->SetSizer( devFrameSizer );
|
this->SetSizer( devFrameSizer );
|
||||||
this->Layout();
|
this->Layout();
|
||||||
|
m_deviceTimer.SetOwner( this, wxID_ANY );
|
||||||
|
|
||||||
this->Centre( wxBOTH );
|
this->Centre( wxBOTH );
|
||||||
|
|
||||||
// Connect Events
|
// Connect Events
|
||||||
|
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( devFrame::OnClose ) );
|
||||||
|
devTree->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( devFrame::OnTreeDoubleClick ), NULL, this );
|
||||||
devTree->Connect( wxEVT_COMMAND_TREE_DELETE_ITEM, wxTreeEventHandler( devFrame::OnDeleteItem ), NULL, this );
|
devTree->Connect( wxEVT_COMMAND_TREE_DELETE_ITEM, wxTreeEventHandler( devFrame::OnDeleteItem ), NULL, this );
|
||||||
devTree->Connect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( devFrame::OnSelectionChanged ), 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_addRemoteButton->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( devFrame::OnAddRemote ), NULL, this );
|
||||||
m_useSelectedButton->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( devFrame::OnUseSelected ), NULL, this );
|
m_useSelectedButton->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( devFrame::OnUseSelected ), NULL, this );
|
||||||
|
this->Connect( wxID_ANY, wxEVT_TIMER, wxTimerEventHandler( devFrame::OnDeviceTimer ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
devFrame::~devFrame()
|
devFrame::~devFrame()
|
||||||
{
|
{
|
||||||
// Disconnect Events
|
// Disconnect Events
|
||||||
|
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( devFrame::OnClose ) );
|
||||||
|
devTree->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( devFrame::OnTreeDoubleClick ), NULL, this );
|
||||||
devTree->Disconnect( wxEVT_COMMAND_TREE_DELETE_ITEM, wxTreeEventHandler( devFrame::OnDeleteItem ), NULL, this );
|
devTree->Disconnect( wxEVT_COMMAND_TREE_DELETE_ITEM, wxTreeEventHandler( devFrame::OnDeleteItem ), NULL, this );
|
||||||
devTree->Disconnect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( devFrame::OnSelectionChanged ), 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_addRemoteButton->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( devFrame::OnAddRemote ), NULL, this );
|
||||||
m_useSelectedButton->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( devFrame::OnUseSelected ), NULL, this );
|
m_useSelectedButton->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( devFrame::OnUseSelected ), NULL, this );
|
||||||
|
this->Disconnect( wxID_ANY, wxEVT_TIMER, wxTimerEventHandler( devFrame::OnDeviceTimer ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <wx/image.h>
|
#include <wx/image.h>
|
||||||
#include <wx/icon.h>
|
#include <wx/icon.h>
|
||||||
#include <wx/notebook.h>
|
#include <wx/notebook.h>
|
||||||
|
#include <wx/timer.h>
|
||||||
#include <wx/frame.h>
|
#include <wx/frame.h>
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
@ -50,17 +51,21 @@ class devFrame : public wxFrame
|
|||||||
wxListCtrl* m_DevInfoList;
|
wxListCtrl* m_DevInfoList;
|
||||||
wxPanel* devParamsPanel;
|
wxPanel* devParamsPanel;
|
||||||
wxListCtrl* m_ParamInfoList;
|
wxListCtrl* m_ParamInfoList;
|
||||||
|
wxTimer m_deviceTimer;
|
||||||
|
|
||||||
// Virtual event handlers, overide them in your derived class
|
// Virtual event handlers, overide them in your derived class
|
||||||
|
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
|
||||||
|
virtual void OnTreeDoubleClick( wxMouseEvent& event ) { event.Skip(); }
|
||||||
virtual void OnDeleteItem( wxTreeEvent& event ) { event.Skip(); }
|
virtual void OnDeleteItem( wxTreeEvent& event ) { event.Skip(); }
|
||||||
virtual void OnSelectionChanged( wxTreeEvent& event ) { event.Skip(); }
|
virtual void OnSelectionChanged( wxTreeEvent& event ) { event.Skip(); }
|
||||||
virtual void OnAddRemote( wxMouseEvent& event ) { event.Skip(); }
|
virtual void OnAddRemote( wxMouseEvent& event ) { event.Skip(); }
|
||||||
virtual void OnUseSelected( wxMouseEvent& event ) { event.Skip(); }
|
virtual void OnUseSelected( wxMouseEvent& event ) { event.Skip(); }
|
||||||
|
virtual void OnDeviceTimer( wxTimerEvent& event ) { event.Skip(); }
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
devFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("CubicSDR :: SDR Devices"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 692,467 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
|
devFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("CubicSDR :: SDR Devices"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 392,467 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
|
||||||
|
|
||||||
~devFrame();
|
~devFrame();
|
||||||
|
|
||||||
|
@ -24,7 +24,8 @@ void SDRDeviceRange::setHigh(double high) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDRDeviceChannel::SDRDeviceChannel() {
|
SDRDeviceChannel::SDRDeviceChannel() {
|
||||||
|
hardwareDC = false;
|
||||||
|
hasCorr = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDRDeviceChannel::~SDRDeviceChannel() {
|
SDRDeviceChannel::~SDRDeviceChannel() {
|
||||||
@ -87,9 +88,26 @@ std::vector<long long> &SDRDeviceChannel::getFilterBandwidths() {
|
|||||||
return filterBandwidths;
|
return filterBandwidths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool& SDRDeviceChannel::hasHardwareDC() const {
|
||||||
|
return hardwareDC;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRDeviceChannel::setHardwareDC(const bool& hardware) {
|
||||||
|
hardwareDC = hardware;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SDRDeviceInfo::SDRDeviceInfo() : name(""), serial(""), available(false), hardwareDC(false) {
|
|
||||||
|
const bool& SDRDeviceChannel::hasCORR() const {
|
||||||
|
return hardwareDC;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRDeviceChannel::setCORR(const bool& hardware) {
|
||||||
|
hardwareDC = hardware;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SDRDeviceInfo::SDRDeviceInfo() : name(""), serial(""), available(false) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,15 +193,6 @@ void SDRDeviceInfo::setHardware(const std::string& hardware) {
|
|||||||
this->hardware = hardware;
|
this->hardware = hardware;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool& SDRDeviceInfo::hasHardwareDC() const {
|
|
||||||
return hardwareDC;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDRDeviceInfo::setHardwareDC(const bool& hardware) {
|
|
||||||
hardwareDC = hardware;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool SDRDeviceInfo::hasTimestamps() const {
|
bool SDRDeviceInfo::hasTimestamps() const {
|
||||||
return timestamps;
|
return timestamps;
|
||||||
}
|
}
|
||||||
|
@ -71,9 +71,16 @@ public:
|
|||||||
std::vector<long long> &getSampleRates();
|
std::vector<long long> &getSampleRates();
|
||||||
std::vector<long long> &getFilterBandwidths();
|
std::vector<long long> &getFilterBandwidths();
|
||||||
|
|
||||||
|
const bool& hasHardwareDC() const;
|
||||||
|
void setHardwareDC(const bool& hardware);
|
||||||
|
|
||||||
|
const bool& hasCORR() const;
|
||||||
|
void setCORR(const bool& corr);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int channel;
|
int channel;
|
||||||
bool fullDuplex, tx, rx;
|
bool fullDuplex, tx, rx, hardwareDC, hasCorr;
|
||||||
SDRDeviceRange rangeGain, rangeLNA, rangeFull, rangeRF;
|
SDRDeviceRange rangeGain, rangeLNA, rangeFull, rangeRF;
|
||||||
std::vector<long long> sampleRates;
|
std::vector<long long> sampleRates;
|
||||||
std::vector<long long> filterBandwidths;
|
std::vector<long long> filterBandwidths;
|
||||||
@ -113,9 +120,6 @@ public:
|
|||||||
const std::string& getHardware() const;
|
const std::string& getHardware() const;
|
||||||
void setHardware(const std::string& hardware);
|
void setHardware(const std::string& hardware);
|
||||||
|
|
||||||
const bool& hasHardwareDC() const;
|
|
||||||
void setHardwareDC(const bool& hardware);
|
|
||||||
|
|
||||||
bool hasTimestamps() const;
|
bool hasTimestamps() const;
|
||||||
void setTimestamps(bool timestamps);
|
void setTimestamps(bool timestamps);
|
||||||
|
|
||||||
@ -134,7 +138,7 @@ private:
|
|||||||
int index;
|
int index;
|
||||||
std::string name, serial, product, manufacturer, tuner;
|
std::string name, serial, product, manufacturer, tuner;
|
||||||
std::string driver, hardware;
|
std::string driver, hardware;
|
||||||
bool timestamps, available, hardwareDC;
|
bool timestamps, available;
|
||||||
|
|
||||||
SoapySDR::Kwargs deviceArgs, streamArgs;
|
SoapySDR::Kwargs deviceArgs, streamArgs;
|
||||||
std::vector<SDRDeviceChannel *> channels;
|
std::vector<SDRDeviceChannel *> channels;
|
||||||
|
@ -7,8 +7,10 @@
|
|||||||
|
|
||||||
std::vector<std::string> SDREnumerator::factories;
|
std::vector<std::string> SDREnumerator::factories;
|
||||||
std::vector<std::string> SDREnumerator::modules;
|
std::vector<std::string> SDREnumerator::modules;
|
||||||
std::vector<SDRDeviceInfo *> SDREnumerator::devs;
|
std::vector<std::string> SDREnumerator::remotes;
|
||||||
|
std::map< std::string, std::vector<SDRDeviceInfo *> > SDREnumerator::devs;
|
||||||
|
bool SDREnumerator::soapy_initialized = false;
|
||||||
|
bool SDREnumerator::has_remote = false;
|
||||||
|
|
||||||
SDREnumerator::SDREnumerator() : IOThread() {
|
SDREnumerator::SDREnumerator() : IOThread() {
|
||||||
|
|
||||||
@ -19,48 +21,73 @@ SDREnumerator::~SDREnumerator() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<SDRDeviceInfo *> *SDREnumerator::enumerate_devices() {
|
std::vector<SDRDeviceInfo *> *SDREnumerator::enumerate_devices(std::string remoteAddr, bool noInit) {
|
||||||
|
|
||||||
if (SDREnumerator::devs.size()) {
|
if (SDREnumerator::devs[remoteAddr].size()) {
|
||||||
return &SDREnumerator::devs;
|
return &SDREnumerator::devs[remoteAddr];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "SoapySDR init.." << std::endl;
|
if (noInit) {
|
||||||
std::cout << "\tAPI Version: v" << SoapySDR::getAPIVersion() << std::endl;
|
return NULL;
|
||||||
std::cout << "\tABI Version: v" << SoapySDR::getABIVersion() << std::endl;
|
}
|
||||||
std::cout << "\tInstall root: " << SoapySDR::getRootPath() << std::endl;
|
|
||||||
|
if (!soapy_initialized) {
|
||||||
|
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();
|
modules = SoapySDR::listModules();
|
||||||
for (size_t i = 0; i < modules.size(); i++) {
|
for (size_t i = 0; i < modules.size(); i++) {
|
||||||
std::cout << "\tModule found: " << modules[i] << std::endl;
|
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;
|
if (modules.empty()) {
|
||||||
SDREnumerator::factories.push_back(it->first);
|
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;
|
||||||
|
|
||||||
|
if (it->first == "remote") {
|
||||||
|
has_remote = true;
|
||||||
|
}
|
||||||
|
SDREnumerator::factories.push_back(it->first);
|
||||||
|
}
|
||||||
|
if (factories.empty()) {
|
||||||
|
std::cout << "No factories found!" << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
soapy_initialized = true;
|
||||||
}
|
}
|
||||||
if (factories.empty()) {
|
|
||||||
std::cout << "No factories found!" << std::endl;
|
std::vector<SoapySDR::Kwargs> results;
|
||||||
|
SoapySDR::Kwargs enumArgs;
|
||||||
|
bool isRemote = false;
|
||||||
|
|
||||||
|
if (remoteAddr.length()) {
|
||||||
|
std::cout << "Enumerating remote address: " << remoteAddr << std::endl;
|
||||||
|
enumArgs["driver"] = "remote";
|
||||||
|
enumArgs["remote"] = remoteAddr;
|
||||||
|
isRemote = true;
|
||||||
|
|
||||||
|
results = SoapySDR::Device::enumerate(enumArgs);
|
||||||
|
} else {
|
||||||
|
results = SoapySDR::Device::enumerate();
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
std::vector<SoapySDR::Kwargs> results = SoapySDR::Device::enumerate();
|
|
||||||
|
|
||||||
// Remote driver test..
|
// Remote driver test..
|
||||||
/* * /
|
/* * /
|
||||||
@ -85,11 +112,34 @@ std::vector<SDRDeviceInfo *> *SDREnumerator::enumerate_devices() {
|
|||||||
|
|
||||||
SDRThread::devs.push_back(remoteDev);
|
SDRThread::devs.push_back(remoteDev);
|
||||||
// */
|
// */
|
||||||
|
if (isRemote) {
|
||||||
|
wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Opening remote server ") + remoteAddr + "..");
|
||||||
|
}
|
||||||
for (size_t i = 0; i < results.size(); i++) {
|
for (size_t i = 0; i < results.size(); i++) {
|
||||||
std::cout << "Found device " << i << std::endl;
|
// std::cout << "Found device " << i << std::endl;
|
||||||
SDRDeviceInfo *dev = new SDRDeviceInfo();
|
SDRDeviceInfo *dev = new SDRDeviceInfo();
|
||||||
for (SoapySDR::Kwargs::const_iterator it = results[i].begin(); it != results[i].end(); ++it) {
|
|
||||||
|
SoapySDR::Kwargs deviceArgs = results[i];
|
||||||
|
SoapySDR::Kwargs streamArgs;
|
||||||
|
|
||||||
|
if (isRemote) {
|
||||||
|
wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, "Querying remote " + remoteAddr + " device #" + std::to_string(i));
|
||||||
|
deviceArgs["remote"] = remoteAddr;
|
||||||
|
if (deviceArgs.count("rtl") != 0) {
|
||||||
|
streamArgs["remote:mtu"] = "8192";
|
||||||
|
streamArgs["remote:format"] = "CS8";
|
||||||
|
streamArgs["remote:window"] = "16384000";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Found local device #") + std::to_string(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deviceArgs.count("rtl") != 0 || (deviceArgs.count("driver") != 0 && (deviceArgs["driver"] == "rtl" || deviceArgs["driver"] == "rtlsdr"))) {
|
||||||
|
streamArgs["buffers"] = "6";
|
||||||
|
streamArgs["buflen"] = "16384";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (SoapySDR::Kwargs::const_iterator it = deviceArgs.begin(); it != deviceArgs.end(); ++it) {
|
||||||
std::cout << " " << it->first << " = " << it->second << std::endl;
|
std::cout << " " << it->first << " = " << it->second << std::endl;
|
||||||
if (it->first == "driver") {
|
if (it->first == "driver") {
|
||||||
dev->setDriver(it->second);
|
dev->setDriver(it->second);
|
||||||
@ -97,8 +147,9 @@ std::vector<SDRDeviceInfo *> *SDREnumerator::enumerate_devices() {
|
|||||||
dev->setName(it->second);
|
dev->setName(it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->setDeviceArgs(results[i]);
|
dev->setDeviceArgs(deviceArgs);
|
||||||
|
dev->setStreamArgs(deviceArgs);
|
||||||
|
|
||||||
std::cout << "Make device " << i << std::endl;
|
std::cout << "Make device " << i << std::endl;
|
||||||
try {
|
try {
|
||||||
@ -125,36 +176,44 @@ std::vector<SDRDeviceInfo *> *SDREnumerator::enumerate_devices() {
|
|||||||
chan->getRFRange().setLow(rfMin);
|
chan->getRFRange().setLow(rfMin);
|
||||||
chan->getRFRange().setHigh(rfMax);
|
chan->getRFRange().setHigh(rfMax);
|
||||||
|
|
||||||
|
std::vector<std::string> freqs = device->listFrequencies(SOAPY_SDR_RX,i);
|
||||||
|
if (std::find(freqs.begin(), freqs.end(), "CORR") != freqs.end()) {
|
||||||
|
chan->setCORR(true);
|
||||||
|
} else {
|
||||||
|
chan->setCORR(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->hasDCOffsetMode(SOAPY_SDR_RX, i)) {
|
||||||
|
chan->setHardwareDC(true);
|
||||||
|
} else {
|
||||||
|
chan->setHardwareDC(false);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<double> rates = device->listSampleRates(SOAPY_SDR_RX, i);
|
std::vector<double> rates = device->listSampleRates(SOAPY_SDR_RX, i);
|
||||||
chan->getSampleRates().assign(rates.begin(), rates.end());
|
chan->getSampleRates().assign(rates.begin(), rates.end());
|
||||||
dev->addChannel(chan);
|
dev->addChannel(chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
SoapySDR::Device::unmake(device);
|
||||||
|
|
||||||
dev->setAvailable(true);
|
dev->setAvailable(true);
|
||||||
} catch (const std::exception &ex) {
|
} catch (const std::exception &ex) {
|
||||||
std::cerr << "Error making device: " << ex.what() << std::endl;
|
std::cerr << "Error making device: " << ex.what() << std::endl;
|
||||||
|
wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Error making device #") + std::to_string(i));
|
||||||
dev->setAvailable(false);
|
dev->setAvailable(false);
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
SDREnumerator::devs.push_back(dev);
|
SDREnumerator::devs[remoteAddr].push_back(dev);
|
||||||
}
|
}
|
||||||
if (results.empty()) {
|
if (SDREnumerator::devs[remoteAddr].empty()) {
|
||||||
std::cout << "No devices found!" << std::endl;
|
wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("No devices found!"));
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
return &SDREnumerator::devs;
|
return &SDREnumerator::devs[remoteAddr];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -163,15 +222,61 @@ void SDREnumerator::run() {
|
|||||||
std::cout << "SDR enumerator starting." << std::endl;
|
std::cout << "SDR enumerator starting." << std::endl;
|
||||||
terminated.store(false);
|
terminated.store(false);
|
||||||
|
|
||||||
std::cout << "Enumerator devices." << std::endl;
|
// if (!remotes.size()) {
|
||||||
SDREnumerator::enumerate_devices();
|
// remotes.push_back("raspberrypi.local");
|
||||||
|
// }
|
||||||
|
|
||||||
|
wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, "Scanning local devices, please wait..");
|
||||||
|
SDREnumerator::enumerate_devices("");
|
||||||
|
|
||||||
|
if (remotes.size()) {
|
||||||
|
std::vector<std::string>::iterator remote_i;
|
||||||
|
for (remote_i = remotes.begin(); remote_i != remotes.end(); remote_i++) {
|
||||||
|
wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, "Scanning devices at " + (*remote_i) + ", please wait..");
|
||||||
|
SDREnumerator::enumerate_devices(*remote_i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << "Reporting enumeration complete." << std::endl;
|
std::cout << "Reporting enumeration complete." << std::endl;
|
||||||
terminated.store(true);
|
terminated.store(true);
|
||||||
wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_DEVICES_READY, "Devices Ready.");
|
wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_DEVICES_READY, "Finished scanning devices.");
|
||||||
|
|
||||||
std::cout << "SDR enumerator done." << std::endl;
|
std::cout << "SDR enumerator done." << std::endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void SDREnumerator::addRemote(std::string remoteAddr) {
|
||||||
|
std::vector<std::string>::iterator remote_i = std::find(remotes.begin(), remotes.end(), remoteAddr);
|
||||||
|
|
||||||
|
if (remote_i != remotes.end()) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
remotes.push_back(remoteAddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDREnumerator::removeRemote(std::string remoteAddr) {
|
||||||
|
std::vector<std::string>::iterator remote_i = std::find(remotes.begin(), remotes.end(), remoteAddr);
|
||||||
|
|
||||||
|
if (remote_i != remotes.end()) {
|
||||||
|
if (devs.find(*remote_i) != devs.end()) {
|
||||||
|
while (devs[*remote_i].size()) {
|
||||||
|
SDRDeviceInfo *devRemove = devs[*remote_i].back();
|
||||||
|
devs[*remote_i].pop_back();
|
||||||
|
delete devRemove;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
remotes.erase(remote_i);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> &SDREnumerator::getRemotes() {
|
||||||
|
return remotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SDREnumerator::hasRemoteModule() {
|
||||||
|
return SDREnumerator::has_remote;
|
||||||
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include "ThreadQueue.h"
|
#include <map>
|
||||||
|
#include <string>
|
||||||
#include "IOThread.h"
|
#include "IOThread.h"
|
||||||
#include "SDRDeviceInfo.h"
|
#include "SDRDeviceInfo.h"
|
||||||
#include "AppConfig.h"
|
#include "AppConfig.h"
|
||||||
@ -18,14 +19,21 @@ private:
|
|||||||
public:
|
public:
|
||||||
SDREnumerator();
|
SDREnumerator();
|
||||||
~SDREnumerator();
|
~SDREnumerator();
|
||||||
enum SDREnumState { SDR_ENUM_DEVICES_READY, SDR_ENUM_TERMINATED, SDR_ENUM_FAILED };
|
enum SDREnumState { SDR_ENUM_DEVICES_READY, SDR_ENUM_MESSAGE, SDR_ENUM_TERMINATED, SDR_ENUM_FAILED };
|
||||||
|
|
||||||
static std::vector<SDRDeviceInfo *> *enumerate_devices();
|
static std::vector<SDRDeviceInfo *> *enumerate_devices(std::string remoteAddr = "", bool noInit=false);
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
|
static void addRemote(std::string remoteAddr);
|
||||||
|
static void removeRemote(std::string remoteAddr);
|
||||||
|
static std::vector<std::string> &getRemotes();
|
||||||
|
static bool hasRemoteModule();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
static bool soapy_initialized, has_remote;
|
||||||
static std::vector<std::string> factories;
|
static std::vector<std::string> factories;
|
||||||
static std::vector<std::string> modules;
|
static std::vector<std::string> modules;
|
||||||
static std::vector<SDRDeviceInfo *> devs;
|
static std::vector<std::string> remotes;
|
||||||
|
static std::map< std::string, std::vector<SDRDeviceInfo *> > devs;
|
||||||
};
|
};
|
||||||
|
@ -39,7 +39,6 @@ void SDRThread::init() {
|
|||||||
deviceConfig.store(wxGetApp().getConfig()->getDevice(devInfo->getDeviceId()));
|
deviceConfig.store(wxGetApp().getConfig()->getDevice(devInfo->getDeviceId()));
|
||||||
DeviceConfig *devConfig = deviceConfig.load();
|
DeviceConfig *devConfig = deviceConfig.load();
|
||||||
|
|
||||||
frequency = wxGetApp().getConfig()->getCenterFreq();
|
|
||||||
ppm.store(devConfig->getPPM());
|
ppm.store(devConfig->getPPM());
|
||||||
direct_sampling_mode.store(devConfig->getDirectSampling());
|
direct_sampling_mode.store(devConfig->getDirectSampling());
|
||||||
|
|
||||||
@ -53,6 +52,7 @@ void SDRThread::init() {
|
|||||||
args["direct_samp"] = std::to_string(devConfig->getDirectSampling());
|
args["direct_samp"] = std::to_string(devConfig->getDirectSampling());
|
||||||
|
|
||||||
if (driverName == "rtl" || driverName == "rtlsdr") {
|
if (driverName == "rtl" || driverName == "rtlsdr") {
|
||||||
|
args["iq_swap"] = std::to_string(devConfig->getIQSwap()?1:0);
|
||||||
args["buffers"] = "6";
|
args["buffers"] = "6";
|
||||||
args["buflen"] = "16384";
|
args["buflen"] = "16384";
|
||||||
hasPPM = true;
|
hasPPM = true;
|
||||||
@ -60,17 +60,30 @@ void SDRThread::init() {
|
|||||||
hasPPM = false;
|
hasPPM = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Initializing device."));
|
||||||
device = SoapySDR::Device::make(args);
|
device = SoapySDR::Device::make(args);
|
||||||
stream = device->setupStream(SOAPY_SDR_RX,"CF32", std::vector<size_t>(), devInfo->getStreamArgs());
|
stream = device->setupStream(SOAPY_SDR_RX,"CF32", std::vector<size_t>(), devInfo->getStreamArgs());
|
||||||
|
|
||||||
|
wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Activating stream."));
|
||||||
device->activateStream(stream);
|
device->activateStream(stream);
|
||||||
device->setSampleRate(SOAPY_SDR_RX,0,sampleRate.load());
|
device->setSampleRate(SOAPY_SDR_RX,0,sampleRate.load());
|
||||||
device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency - offset.load());
|
device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency - offset.load());
|
||||||
if (hasPPM) {
|
SDRDeviceChannel *chan = devInfo->getRxChannel();
|
||||||
device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm);
|
if (chan->hasCORR()) {
|
||||||
|
hasPPM.store(true);
|
||||||
|
device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm.load());
|
||||||
|
} else {
|
||||||
|
hasPPM.store(false);
|
||||||
}
|
}
|
||||||
|
if (chan->hasHardwareDC()) {
|
||||||
|
hasHardwareDC.store(true);
|
||||||
|
wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Found hardware DC offset correction support, internal disabled."));
|
||||||
|
device->setDCOffsetMode(SOAPY_SDR_RX, chan->getChannel(), true);
|
||||||
|
} else {
|
||||||
|
hasHardwareDC.store(false);
|
||||||
|
}
|
||||||
|
|
||||||
device->setGainMode(SOAPY_SDR_RX,0,true);
|
device->setGainMode(SOAPY_SDR_RX,0,true);
|
||||||
hasHardwareDC = devInfo->hasHardwareDC();
|
|
||||||
|
|
||||||
numElems = getOptimalElementCount(sampleRate.load(), 60);
|
numElems = getOptimalElementCount(sampleRate.load(), 60);
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
SDRThread();
|
SDRThread();
|
||||||
~SDRThread();
|
~SDRThread();
|
||||||
enum SDRThreadState { SDR_THREAD_TERMINATED, SDR_THREAD_FAILED };
|
enum SDRThreadState { SDR_THREAD_MESSAGE, SDR_THREAD_TERMINATED, SDR_THREAD_FAILED };
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user