diff --git a/CMakeLists.txt b/CMakeLists.txt index 4634cb7..cf437d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 6ffbb89..61af844 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -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 *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 *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(); diff --git a/src/AppFrame.h b/src/AppFrame.h index b257628..26c0c61 100644 --- a/src/AppFrame.h +++ b/src/AppFrame.h @@ -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 diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 67cbdc4..c4870e5 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -18,6 +18,8 @@ #include "CoreFoundation/CoreFoundation.h" #endif +#include + 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::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() { diff --git a/src/CubicSDR.h b/src/CubicSDR.h index d7ae7fd..d234af6 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -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 *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 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 [] = diff --git a/src/forms/SDRDevices/SDRDevices.cpp b/src/forms/SDRDevices/SDRDevices.cpp index a76f317..bb58265 100644 --- a/src/forms/SDRDevices/SDRDevices.cpp +++ b/src/forms/SDRDevices/SDRDevices.cpp @@ -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" \ No newline at end of file diff --git a/src/forms/SDRDevices/SDRDevices.fbp b/src/forms/SDRDevices/SDRDevices.fbp index fd35de0..3a693d9 100644 --- a/src/forms/SDRDevices/SDRDevices.fbp +++ b/src/forms/SDRDevices/SDRDevices.fbp @@ -137,13 +137,13 @@ devFrameSizer - wxHORIZONTAL + wxVERTICAL none 5 - wxEXPAND + wxEXPAND | wxALL 1 - + 1 1 1 @@ -178,7 +178,7 @@ 0 1 - devTree + m_panel3 1 @@ -188,13 +188,12 @@ Resizable 1 - wxTR_DEFAULT_STYLE 0 - + wxTAB_TRAVERSAL @@ -217,200 +216,740 @@ - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND - 2 - - 1 - 1 - 1 - 1 - - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 0 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - devTabs - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Device - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 0 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - devInfoPanel - 1 - - - protected - 1 - - Resizable - 1 - - - 0 - - - - wxTAB_TRAVERSAL - - - - - - - - - - - - - - - - - - - - - - - - + + + bSizer4 + wxHORIZONTAL + none + + 5 + wxEXPAND | wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 - devInfoSizer - wxVERTICAL - none - - 5 - wxEXPAND - 1 - + 1 + m_panel6 + 1 + + + protected + 1 + + Resizable + 1 + + + 0 + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer6 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + devTree + 1 + + + protected + 1 + + Resizable + 1 + + wxTR_DEFAULT_STYLE + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnDeleteItem + + + + + + + + + + + + + + OnSelectionChanged + + + + + + + + 5 + wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_panel4 + 1 + + + protected + 1 + + Resizable + 1 + + + 0 + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer5 + wxHORIZONTAL + none + + 5 + wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Add Remote + + 0 + + + 0 + + 1 + m_addRemoteButton + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + OnAddRemote + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Use Selected + + 0 + + + 0 + + 1 + m_useSelectedButton + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + OnUseSelected + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 0 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + devTabs + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Device + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 0 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + devInfoPanel + 1 + + + protected + 1 + + Resizable + 1 + + + 0 + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + devInfoSizer + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_DevInfoList + 1 + + + protected + 1 + + Resizable + 1 + + wxLC_ICON + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Parameters + 0 + 1 1 1 @@ -445,7 +984,7 @@ 0 1 - m_DevInfoList + devParamsPanel 1 @@ -455,17 +994,12 @@ Resizable 1 - wxLC_ICON 0 - - wxFILTER_NONE - wxDefaultValidator - - + wxTAB_TRAVERSAL @@ -476,217 +1010,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Parameters - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - devParamsPanel - 1 - - - protected - 1 - - Resizable - 1 - - - 0 - - - - wxTAB_TRAVERSAL - - - - - - - - - - - - - - - - - - - - - - - - - - devParamsSizer - wxVERTICAL - none - - 5 - wxEXPAND - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - m_ParamInfoList - 1 - - - protected - 1 - - Resizable - 1 - - wxLC_ICON - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -700,6 +1023,117 @@ + + + devParamsSizer + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_ParamInfoList + 1 + + + protected + 1 + + Resizable + 1 + + wxLC_ICON + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -708,62 +1142,6 @@ - - - - 1 - 1 - - - 0 - wxID_ANY - dMenu - - - devMenuBar - protected - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - File - devFileMenu - protected - - - Edit - devEditMenu - protected - - diff --git a/src/forms/SDRDevices/SDRDevices.h b/src/forms/SDRDevices/SDRDevices.h index 7b9637e..f823114 100644 --- a/src/forms/SDRDevices/SDRDevices.h +++ b/src/forms/SDRDevices/SDRDevices.h @@ -1 +1,24 @@ -#pragma once \ No newline at end of file +#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 *devs; + std::vector::iterator devs_i; + std::map devItems; + std::map::iterator devItems_i; + SDRDeviceInfo *dev = NULL; +}; \ No newline at end of file diff --git a/src/forms/SDRDevices/SDRDevicesForm.cpp b/src/forms/SDRDevices/SDRDevicesForm.cpp index 3794d03..2ca6e05 100644 --- a/src/forms/SDRDevices/SDRDevicesForm.cpp +++ b/src/forms/SDRDevices/SDRDevicesForm.cpp @@ -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 ); + } diff --git a/src/forms/SDRDevices/SDRDevicesForm.h b/src/forms/SDRDevices/SDRDevicesForm.h index 7e196b7..8795ae9 100644 --- a/src/forms/SDRDevices/SDRDevicesForm.h +++ b/src/forms/SDRDevices/SDRDevicesForm.h @@ -17,14 +17,14 @@ #include #include #include -#include +#include #include #include +#include #include #include #include #include -#include #include /////////////////////////////////////////////////////////////////////////// @@ -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: diff --git a/src/sdr/SDREnumerator.cpp b/src/sdr/SDREnumerator.cpp new file mode 100644 index 0000000..1223acd --- /dev/null +++ b/src/sdr/SDREnumerator.cpp @@ -0,0 +1,158 @@ +#include "SDREnumerator.h" +#include "CubicSDRDefs.h" +#include +#include "CubicSDR.h" +#include + + +std::vector SDREnumerator::factories; +std::vector SDREnumerator::modules; +std::vector SDREnumerator::devs; + + +SDREnumerator::SDREnumerator() : IOThread() { + +} + +SDREnumerator::~SDREnumerator() { + +} + + +std::vector *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 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; + +} + + diff --git a/src/sdr/SDREnumerator.h b/src/sdr/SDREnumerator.h new file mode 100644 index 0000000..8c7e8ea --- /dev/null +++ b/src/sdr/SDREnumerator.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include "ThreadQueue.h" +#include "IOThread.h" +#include "SDRDeviceInfo.h" +#include "AppConfig.h" + +#include +#include +#include +#include + + +class SDREnumerator: public IOThread { +private: + +public: + SDREnumerator(); + ~SDREnumerator(); + enum SDREnumState { SDR_ENUM_DEVICES_READY, SDR_ENUM_TERMINATED, SDR_ENUM_FAILED }; + + static std::vector *enumerate_devices(); + + void run(); + +protected: + static std::vector factories; + static std::vector modules; + static std::vector devs; +}; diff --git a/src/sdr/SoapySDRThread.cpp b/src/sdr/SoapySDRThread.cpp index 710547b..6f653ae 100644 --- a/src/sdr/SoapySDRThread.cpp +++ b/src/sdr/SoapySDRThread.cpp @@ -5,11 +5,6 @@ #include -std::vector SDRThread::factories; -std::vector SDRThread::modules; -std::vector SDRThread::devs; - - SDRThread::SDRThread() : IOThread() { device = NULL; @@ -39,126 +34,6 @@ SDRThread::~SDRThread() { } - -std::vector *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 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; diff --git a/src/sdr/SoapySDRThread.h b/src/sdr/SoapySDRThread.h index 327f25d..64370fb 100644 --- a/src/sdr/SoapySDRThread.h +++ b/src/sdr/SoapySDRThread.h @@ -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 *enumerate_devices(); - void run(); SDRDeviceInfo *getDevice(); @@ -73,9 +71,6 @@ public: int getDirectSampling(); protected: - static std::vector factories; - static std::vector modules; - static std::vector devs; SoapySDR::Stream *stream; SoapySDR::Device *device; void *buffs[1];