SDR Thread rework, async device init.
- Preparing for new device selection/configuration dialog.
This commit is contained in:
parent
d7d1008d89
commit
4ce8bc1781
|
@ -234,6 +234,7 @@ ENDIF(USE_AUDIO_OSS)
|
||||||
ENDIF(UNIX AND NOT APPLE)
|
ENDIF(UNIX AND NOT APPLE)
|
||||||
|
|
||||||
IF (APPLE)
|
IF (APPLE)
|
||||||
|
SET(CMAKE_OSX_DEPLOYMENT_TARGET, "10.9")
|
||||||
IF (USE_RTL_SDR)
|
IF (USE_RTL_SDR)
|
||||||
SET(RTLSDR_INCLUDE "/opt/local/include" CACHE FILEPATH "RTL-SDR Include Path")
|
SET(RTLSDR_INCLUDE "/opt/local/include" CACHE FILEPATH "RTL-SDR Include Path")
|
||||||
SET(RTLSDR_LIB "/opt/local/lib" CACHE FILEPATH "RTL-SDR Lib Path")
|
SET(RTLSDR_LIB "/opt/local/lib" CACHE FILEPATH "RTL-SDR Lib Path")
|
||||||
|
@ -301,6 +302,8 @@ SET (cubicsdr_sources
|
||||||
src/process/FFTDataDistributor.cpp
|
src/process/FFTDataDistributor.cpp
|
||||||
src/process/SpectrumVisualDataThread.cpp
|
src/process/SpectrumVisualDataThread.cpp
|
||||||
src/ui/GLPanel.cpp
|
src/ui/GLPanel.cpp
|
||||||
|
src/forms/SDRDevices/SDRDevices.cpp
|
||||||
|
src/forms/SDRDevices/SDRDevicesForm.cpp
|
||||||
external/rtaudio/RtAudio.cpp
|
external/rtaudio/RtAudio.cpp
|
||||||
external/lodepng/lodepng.cpp
|
external/lodepng/lodepng.cpp
|
||||||
external/tinyxml/tinyxml.cpp
|
external/tinyxml/tinyxml.cpp
|
||||||
|
@ -360,6 +363,8 @@ SET (cubicsdr_headers
|
||||||
src/ui/UITestCanvas.h
|
src/ui/UITestCanvas.h
|
||||||
src/ui/UITestContext.cpp
|
src/ui/UITestContext.cpp
|
||||||
src/ui/UITestContext.h
|
src/ui/UITestContext.h
|
||||||
|
src/forms/SDRDevices/SDRDevices.h
|
||||||
|
src/forms/SDRDevices/SDRDevicesForm.h
|
||||||
external/rtaudio/RtAudio.h
|
external/rtaudio/RtAudio.h
|
||||||
external/lodepng/lodepng.h
|
external/lodepng/lodepng.h
|
||||||
external/tinyxml/tinyxml.h
|
external/tinyxml/tinyxml.h
|
||||||
|
@ -392,21 +397,23 @@ ENDIF()
|
||||||
|
|
||||||
set(REG_EXT "[^/]*([.]cpp|[.]c|[.]h|[.]hpp)$")
|
set(REG_EXT "[^/]*([.]cpp|[.]c|[.]h|[.]hpp)$")
|
||||||
|
|
||||||
SOURCE_GROUP("Base" REGULAR_EXPRESSION src/${REG_EXT})
|
SOURCE_GROUP("Base" REGULAR_EXPRESSION "src/${REG_EXT}")
|
||||||
SOURCE_GROUP("SDR" REGULAR_EXPRESSION src/sdr/${REG_EXT})
|
SOURCE_GROUP("Forms\\SDRDevices" REGULAR_EXPRESSION "src/forms/SDRDevices/${REG_EXT}")
|
||||||
SOURCE_GROUP("Demodulator" REGULAR_EXPRESSION src/demod/${REG_EXT})
|
SOURCE_GROUP("SDR" REGULAR_EXPRESSION "src/sdr/${REG_EXT}")
|
||||||
SOURCE_GROUP("Audio" REGULAR_EXPRESSION src/audio/${REG_EXT})
|
SOURCE_GROUP("Demodulator" REGULAR_EXPRESSION "src/demod/${REG_EXT}")
|
||||||
SOURCE_GROUP("Utility" REGULAR_EXPRESSION src/util/${REG_EXT})
|
SOURCE_GROUP("Audio" REGULAR_EXPRESSION "src/audio/${REG_EXT}")
|
||||||
SOURCE_GROUP("Panel" REGULAR_EXPRESSION src/panel/${REG_EXT})
|
SOURCE_GROUP("Utility" REGULAR_EXPRESSION "src/util/${REG_EXT}")
|
||||||
SOURCE_GROUP("Visual" REGULAR_EXPRESSION src/visual/${REG_EXT})
|
SOURCE_GROUP("Visual" REGULAR_EXPRESSION "src/visual/${REG_EXT}")
|
||||||
SOURCE_GROUP("Process" REGULAR_EXPRESSION src/process/${REG_EXT})
|
SOURCE_GROUP("Panel" REGULAR_EXPRESSION "src/panel/${REG_EXT}")
|
||||||
SOURCE_GROUP("UI" REGULAR_EXPRESSION src/ui/${REG_EXT})
|
SOURCE_GROUP("Process" REGULAR_EXPRESSION "src/process/${REG_EXT}")
|
||||||
SOURCE_GROUP("_ext-RTAudio" REGULAR_EXPRESSION external/rtaudio/.*${REG_EXT})
|
SOURCE_GROUP("UI" REGULAR_EXPRESSION "src/ui/${REG_EXT}")
|
||||||
SOURCE_GROUP("_ext-LodePNG" REGULAR_EXPRESSION external/lodepng/.*${REG_EXT})
|
SOURCE_GROUP("_ext-RTAudio" REGULAR_EXPRESSION "external/rtaudio/.*${REG_EXT}")
|
||||||
SOURCE_GROUP("_ext-TinyXML" REGULAR_EXPRESSION external/tinyxml/.*${REG_EXT})
|
SOURCE_GROUP("_ext-LodePNG" REGULAR_EXPRESSION "external/lodepng/.*${REG_EXT}")
|
||||||
SOURCE_GROUP("_ext-CubicVR2" REGULAR_EXPRESSION external/cubicvr2/.*${REG_EXT})
|
SOURCE_GROUP("_ext-TinyXML" REGULAR_EXPRESSION "external/tinyxml/.*${REG_EXT}")
|
||||||
|
SOURCE_GROUP("_ext-CubicVR2" REGULAR_EXPRESSION "external/cubicvr2/.*${REG_EXT}")
|
||||||
|
|
||||||
include_directories (
|
include_directories (
|
||||||
|
${PROJECT_SOURCE_DIR}/src/forms/SDRDevices
|
||||||
${PROJECT_SOURCE_DIR}/src/sdr
|
${PROJECT_SOURCE_DIR}/src/sdr
|
||||||
${PROJECT_SOURCE_DIR}/src/demod
|
${PROJECT_SOURCE_DIR}/src/demod
|
||||||
${PROJECT_SOURCE_DIR}/src/audio
|
${PROJECT_SOURCE_DIR}/src/audio
|
||||||
|
|
|
@ -292,29 +292,29 @@ AppFrame::AppFrame() :
|
||||||
std::vector<SDRDeviceInfo *> *devs = wxGetApp().getDevices();
|
std::vector<SDRDeviceInfo *> *devs = wxGetApp().getDevices();
|
||||||
std::vector<SDRDeviceInfo *>::iterator devs_i;
|
std::vector<SDRDeviceInfo *>::iterator devs_i;
|
||||||
|
|
||||||
if (devs->size() > 1) {
|
// if (devs->size() > 1) {
|
||||||
|
//
|
||||||
menu = new wxMenu;
|
// menu = new wxMenu;
|
||||||
|
//
|
||||||
int p = 0;
|
// int p = 0;
|
||||||
for (devs_i = devs->begin(); devs_i != devs->end(); devs_i++) {
|
// for (devs_i = devs->begin(); devs_i != devs->end(); devs_i++) {
|
||||||
std::string devName = (*devs_i)->getName();
|
// std::string devName = (*devs_i)->getName();
|
||||||
if ((*devs_i)->isAvailable()) {
|
// if ((*devs_i)->isAvailable()) {
|
||||||
devName.append(": ");
|
// devName.append(": ");
|
||||||
devName.append((*devs_i)->getProduct());
|
// devName.append((*devs_i)->getProduct());
|
||||||
devName.append(" [");
|
// devName.append(" [");
|
||||||
devName.append((*devs_i)->getSerial());
|
// devName.append((*devs_i)->getSerial());
|
||||||
devName.append("]");
|
// devName.append("]");
|
||||||
} else {
|
// } else {
|
||||||
devName.append(" (In Use?)");
|
// devName.append(" (In Use?)");
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
menu->AppendRadioItem(wxID_DEVICE_ID + p, devName)->Check(wxGetApp().getDevice() == p);
|
// menu->AppendRadioItem(wxID_DEVICE_ID + p, devName); //->Check(wxGetApp().getDevice() == p);
|
||||||
p++;
|
// p++;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
menuBar->Append(menu, wxT("Input &Device"));
|
// menuBar->Append(menu, wxT("Input &Device"));
|
||||||
}
|
// }
|
||||||
|
|
||||||
menu = new wxMenu;
|
menu = new wxMenu;
|
||||||
|
|
||||||
|
|
235
src/CubicSDR.cpp
235
src/CubicSDR.cpp
|
@ -21,7 +21,7 @@
|
||||||
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),
|
||||||
sdrThread(NULL), sdrPostThread(NULL), spectrumVisualThread(NULL), demodVisualThread(NULL), pipeSDRCommand(NULL), pipeSDRIQData(NULL), pipeIQVisualData(NULL), pipeAudioVisualData(NULL), t_SDR(NULL), t_PostSDR(NULL) {
|
sdrThread(NULL), sdrPostThread(NULL), spectrumVisualThread(NULL), demodVisualThread(NULL), pipeSDRIQData(NULL), pipeIQVisualData(NULL), pipeAudioVisualData(NULL), t_SDR(NULL), t_PostSDR(NULL) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,12 +81,9 @@ bool CubicSDR::OnInit() {
|
||||||
|
|
||||||
// I/Q Data
|
// I/Q Data
|
||||||
pipeSDRIQData = new SDRThreadIQDataQueue();
|
pipeSDRIQData = new SDRThreadIQDataQueue();
|
||||||
pipeSDRCommand = new SDRThreadCommandQueue();
|
|
||||||
|
|
||||||
pipeSDRIQData->set_max_num_items(100);
|
pipeSDRIQData->set_max_num_items(100);
|
||||||
|
|
||||||
sdrThread = new SDRThread();
|
sdrThread = new SDRThread();
|
||||||
sdrThread->setInputQueue("SDRCommandQueue",pipeSDRCommand);
|
|
||||||
sdrThread->setOutputQueue("IQDataOutput",pipeSDRIQData);
|
sdrThread->setOutputQueue("IQDataOutput",pipeSDRIQData);
|
||||||
|
|
||||||
sdrPostThread = new SDRPostThread();
|
sdrPostThread = new SDRPostThread();
|
||||||
|
@ -95,60 +92,13 @@ bool CubicSDR::OnInit() {
|
||||||
sdrPostThread->setOutputQueue("IQVisualDataOutput", pipeIQVisualData);
|
sdrPostThread->setOutputQueue("IQVisualDataOutput", pipeIQVisualData);
|
||||||
sdrPostThread->setOutputQueue("IQDataOutput", pipeWaterfallIQVisualData);
|
sdrPostThread->setOutputQueue("IQDataOutput", pipeWaterfallIQVisualData);
|
||||||
|
|
||||||
std::vector<SDRDeviceInfo *>::iterator devs_i;
|
|
||||||
|
|
||||||
// SDRThread::enumerate_rtl(&devs);
|
|
||||||
devs = SDRThread::enumerate_devices();
|
|
||||||
SDRDeviceInfo *dev = NULL;
|
|
||||||
|
|
||||||
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 false;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev = (*devs)[devId];
|
|
||||||
|
|
||||||
sdrThread->setDeviceId(devId);
|
|
||||||
} else if (devs->size() == 1) {
|
|
||||||
dev = (*devs)[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dev) {
|
|
||||||
wxMessageDialog *info;
|
|
||||||
info = new wxMessageDialog(NULL, wxT("\x28\u256F\xB0\u25A1\xB0\uFF09\u256F\uFE35\x20\u253B\u2501\u253B"), wxT("RTL-SDR device not found"), wxOK | wxICON_ERROR);
|
|
||||||
info->ShowModal();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
t_PostSDR = new std::thread(&SDRPostThread::threadMain, sdrPostThread);
|
t_PostSDR = new std::thread(&SDRPostThread::threadMain, sdrPostThread);
|
||||||
t_SDR = new std::thread(&SDRThread::threadMain, sdrThread);
|
|
||||||
t_SpectrumVisual = new std::thread(&SpectrumVisualDataThread::threadMain, spectrumVisualThread);
|
t_SpectrumVisual = new std::thread(&SpectrumVisualDataThread::threadMain, spectrumVisualThread);
|
||||||
t_DemodVisual = new std::thread(&SpectrumVisualDataThread::threadMain, demodVisualThread);
|
t_DemodVisual = new std::thread(&SpectrumVisualDataThread::threadMain, demodVisualThread);
|
||||||
|
|
||||||
|
t_SDR = new std::thread(&SDRThread::threadMain, sdrThread);
|
||||||
|
|
||||||
appframe = new AppFrame();
|
appframe = new AppFrame();
|
||||||
if (dev != NULL) {
|
|
||||||
appframe->initDeviceParams(dev->getDeviceId());
|
|
||||||
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId());
|
|
||||||
ppm = devConfig->getPPM();
|
|
||||||
offset = devConfig->getOffset();
|
|
||||||
directSamplingMode = devConfig->getDirectSampling();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
int main_policy;
|
int main_policy;
|
||||||
|
@ -167,9 +117,10 @@ int CubicSDR::OnExit() {
|
||||||
demodMgr.terminateAll();
|
demodMgr.terminateAll();
|
||||||
|
|
||||||
std::cout << "Terminating SDR thread.." << std::endl;
|
std::cout << "Terminating SDR thread.." << std::endl;
|
||||||
sdrThread->terminate();
|
if (!sdrThread->isTerminated()) {
|
||||||
t_SDR->join();
|
sdrThread->terminate();
|
||||||
|
t_SDR->join();
|
||||||
|
}
|
||||||
std::cout << "Terminating SDR post-processing thread.." << std::endl;
|
std::cout << "Terminating SDR post-processing thread.." << std::endl;
|
||||||
sdrPostThread->terminate();
|
sdrPostThread->terminate();
|
||||||
t_PostSDR->join();
|
t_PostSDR->join();
|
||||||
|
@ -182,7 +133,6 @@ int CubicSDR::OnExit() {
|
||||||
t_DemodVisual->join();
|
t_DemodVisual->join();
|
||||||
|
|
||||||
delete sdrThread;
|
delete sdrThread;
|
||||||
delete t_SDR;
|
|
||||||
|
|
||||||
delete sdrPostThread;
|
delete sdrPostThread;
|
||||||
delete t_PostSDR;
|
delete t_PostSDR;
|
||||||
|
@ -192,8 +142,6 @@ int CubicSDR::OnExit() {
|
||||||
delete t_DemodVisual;
|
delete t_DemodVisual;
|
||||||
delete demodVisualThread;
|
delete demodVisualThread;
|
||||||
|
|
||||||
delete pipeSDRCommand;
|
|
||||||
|
|
||||||
delete pipeIQVisualData;
|
delete pipeIQVisualData;
|
||||||
delete pipeAudioVisualData;
|
delete pipeAudioVisualData;
|
||||||
delete pipeSDRIQData;
|
delete pipeSDRIQData;
|
||||||
|
@ -235,14 +183,85 @@ bool CubicSDR::OnCmdLineParsed(wxCmdLineParser& parser) {
|
||||||
return true;
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
if (state == SDRThread::SDR_THREAD_FAILED) {
|
||||||
|
wxMessageDialog *info;
|
||||||
|
info = new wxMessageDialog(NULL, message, wxT("Error initializing device"), wxOK | wxICON_ERROR);
|
||||||
|
info->ShowModal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CubicSDR::setFrequency(long long freq) {
|
void CubicSDR::setFrequency(long long freq) {
|
||||||
if (freq < sampleRate / 2) {
|
if (freq < sampleRate / 2) {
|
||||||
freq = sampleRate / 2;
|
freq = sampleRate / 2;
|
||||||
}
|
}
|
||||||
frequency = freq;
|
frequency = freq;
|
||||||
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_TUNE);
|
sdrThread->setFrequency(freq);
|
||||||
command.llong_value = freq;
|
|
||||||
pipeSDRCommand->push(command);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
long long CubicSDR::getOffset() {
|
long long CubicSDR::getOffset() {
|
||||||
|
@ -251,21 +270,16 @@ long long CubicSDR::getOffset() {
|
||||||
|
|
||||||
void CubicSDR::setOffset(long long ofs) {
|
void CubicSDR::setOffset(long long ofs) {
|
||||||
offset = ofs;
|
offset = ofs;
|
||||||
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_OFFSET);
|
sdrThread->setOffset(offset);
|
||||||
command.llong_value = ofs;
|
SDRDeviceInfo *dev = getDevice();
|
||||||
pipeSDRCommand->push(command);
|
|
||||||
|
|
||||||
SDRDeviceInfo *dev = (*getDevices())[getDevice()];
|
|
||||||
config.getDevice(dev->getDeviceId())->setOffset(ofs);
|
config.getDevice(dev->getDeviceId())->setOffset(ofs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubicSDR::setDirectSampling(int mode) {
|
void CubicSDR::setDirectSampling(int mode) {
|
||||||
directSamplingMode = mode;
|
directSamplingMode = mode;
|
||||||
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_DIRECT_SAMPLING);
|
sdrThread->setDirectSampling(mode);
|
||||||
command.llong_value = mode;
|
|
||||||
pipeSDRCommand->push(command);
|
|
||||||
|
|
||||||
SDRDeviceInfo *dev = (*getDevices())[getDevice()];
|
SDRDeviceInfo *dev = getDevice();
|
||||||
config.getDevice(dev->getDeviceId())->setDirectSampling(mode);
|
config.getDevice(dev->getDeviceId())->setDirectSampling(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +289,7 @@ int CubicSDR::getDirectSampling() {
|
||||||
|
|
||||||
void CubicSDR::setSwapIQ(bool swapIQ) {
|
void CubicSDR::setSwapIQ(bool swapIQ) {
|
||||||
sdrPostThread->setSwapIQ(swapIQ);
|
sdrPostThread->setSwapIQ(swapIQ);
|
||||||
SDRDeviceInfo *dev = (*getDevices())[getDevice()];
|
SDRDeviceInfo *dev = getDevice();
|
||||||
config.getDevice(dev->getDeviceId())->setIQSwap(swapIQ);
|
config.getDevice(dev->getDeviceId())->setIQSwap(swapIQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,6 +301,29 @@ long long CubicSDR::getFrequency() {
|
||||||
return frequency;
|
return frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CubicSDR::setSampleRate(long long rate_in) {
|
||||||
|
sampleRate = rate_in;
|
||||||
|
sdrThread->setSampleRate(sampleRate);
|
||||||
|
setFrequency(frequency);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CubicSDR::setDevice(int deviceId) {
|
||||||
|
|
||||||
|
// SDRDeviceInfo *dev = (*getDevices())[deviceId];
|
||||||
|
// DeviceConfig *devConfig = config.getDevice(dev->getDeviceId());
|
||||||
|
|
||||||
|
// sdrThread->setDevice(devConfig);
|
||||||
|
//
|
||||||
|
// setPPM(devConfig->getPPM());
|
||||||
|
// setDirectSampling(devConfig->getDirectSampling());
|
||||||
|
// setSwapIQ(devConfig->getIQSwap());
|
||||||
|
// setOffset(devConfig->getOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
SDRDeviceInfo *CubicSDR::getDevice() {
|
||||||
|
return sdrThread->getDevice();
|
||||||
|
}
|
||||||
|
|
||||||
ScopeVisualProcessor *CubicSDR::getScopeProcessor() {
|
ScopeVisualProcessor *CubicSDR::getScopeProcessor() {
|
||||||
return &scopeProcessor;
|
return &scopeProcessor;
|
||||||
}
|
}
|
||||||
|
@ -327,14 +364,6 @@ void CubicSDR::bindDemodulator(DemodulatorInstance *demod) {
|
||||||
sdrPostThread->bindDemodulator(demod);
|
sdrPostThread->bindDemodulator(demod);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubicSDR::setSampleRate(long long rate_in) {
|
|
||||||
sampleRate = rate_in;
|
|
||||||
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_SAMPLERATE);
|
|
||||||
command.llong_value = rate_in;
|
|
||||||
pipeSDRCommand->push(command);
|
|
||||||
setFrequency(frequency);
|
|
||||||
}
|
|
||||||
|
|
||||||
long long CubicSDR::getSampleRate() {
|
long long CubicSDR::getSampleRate() {
|
||||||
return sampleRate;
|
return sampleRate;
|
||||||
}
|
}
|
||||||
|
@ -351,57 +380,31 @@ std::vector<SDRDeviceInfo*>* CubicSDR::getDevices() {
|
||||||
return devs;
|
return devs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubicSDR::setDevice(int deviceId) {
|
|
||||||
sdrThread->setDeviceId(deviceId);
|
|
||||||
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_DEVICE);
|
|
||||||
command.llong_value = deviceId;
|
|
||||||
pipeSDRCommand->push(command);
|
|
||||||
|
|
||||||
SDRDeviceInfo *dev = (*getDevices())[deviceId];
|
|
||||||
DeviceConfig *devConfig = config.getDevice(dev->getDeviceId());
|
|
||||||
|
|
||||||
setPPM(devConfig->getPPM());
|
|
||||||
setDirectSampling(devConfig->getDirectSampling());
|
|
||||||
setSwapIQ(devConfig->getIQSwap());
|
|
||||||
setOffset(devConfig->getOffset());
|
|
||||||
}
|
|
||||||
|
|
||||||
int CubicSDR::getDevice() {
|
|
||||||
return sdrThread->getDeviceId();
|
|
||||||
}
|
|
||||||
|
|
||||||
AppConfig *CubicSDR::getConfig() {
|
AppConfig *CubicSDR::getConfig() {
|
||||||
return &config;
|
return &config;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubicSDR::saveConfig() {
|
void CubicSDR::saveConfig() {
|
||||||
config.save();
|
#warning Configuration Save Disabled
|
||||||
|
// config.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubicSDR::setPPM(int ppm_in) {
|
void CubicSDR::setPPM(int ppm_in) {
|
||||||
if (sdrThread->getDeviceId() < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ppm = ppm_in;
|
ppm = ppm_in;
|
||||||
|
sdrThread->setPPM(ppm);
|
||||||
|
|
||||||
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_PPM);
|
SDRDeviceInfo *dev = getDevice();
|
||||||
command.llong_value = ppm;
|
if (dev) {
|
||||||
pipeSDRCommand->push(command);
|
config.getDevice(dev->getDeviceId())->setPPM(ppm_in);
|
||||||
|
}
|
||||||
SDRDeviceInfo *dev = (*getDevices())[getDevice()];
|
|
||||||
|
|
||||||
config.getDevice(dev->getDeviceId())->setPPM(ppm_in);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CubicSDR::getPPM() {
|
int CubicSDR::getPPM() {
|
||||||
if (sdrThread->getDeviceId() < 0) {
|
SDRDeviceInfo *dev = sdrThread->getDevice();
|
||||||
return 0;
|
if (dev) {
|
||||||
|
ppm = config.getDevice(dev->getDeviceId())->getPPM();
|
||||||
}
|
}
|
||||||
SDRDeviceInfo *dev = (*getDevices())[getDevice()];
|
|
||||||
|
|
||||||
SDRThreadCommand command_ppm(SDRThreadCommand::SDR_THREAD_CMD_SET_PPM);
|
|
||||||
ppm = config.getDevice(dev->getDeviceId())->getPPM();
|
|
||||||
|
|
||||||
return ppm;
|
return ppm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,9 @@ public:
|
||||||
virtual void OnInitCmdLine(wxCmdLineParser& parser);
|
virtual void OnInitCmdLine(wxCmdLineParser& parser);
|
||||||
virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
|
virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
|
||||||
|
|
||||||
|
SDRDeviceInfo *deviceSelector();
|
||||||
|
void sdrThreadNotify(SDRThread::SDRThreadState state, std::string message);
|
||||||
|
|
||||||
void setFrequency(long long freq);
|
void setFrequency(long long freq);
|
||||||
long long getFrequency();
|
long long getFrequency();
|
||||||
|
|
||||||
|
@ -59,7 +62,7 @@ public:
|
||||||
|
|
||||||
std::vector<SDRDeviceInfo *> *getDevices();
|
std::vector<SDRDeviceInfo *> *getDevices();
|
||||||
void setDevice(int deviceId);
|
void setDevice(int deviceId);
|
||||||
int getDevice();
|
SDRDeviceInfo * getDevice();
|
||||||
|
|
||||||
ScopeVisualProcessor *getScopeProcessor();
|
ScopeVisualProcessor *getScopeProcessor();
|
||||||
SpectrumVisualProcessor *getSpectrumProcessor();
|
SpectrumVisualProcessor *getSpectrumProcessor();
|
||||||
|
@ -105,7 +108,7 @@ private:
|
||||||
SpectrumVisualDataThread *spectrumVisualThread;
|
SpectrumVisualDataThread *spectrumVisualThread;
|
||||||
SpectrumVisualDataThread *demodVisualThread;
|
SpectrumVisualDataThread *demodVisualThread;
|
||||||
|
|
||||||
SDRThreadCommandQueue* pipeSDRCommand;
|
// SDRThreadCommandQueue* pipeSDRCommand;
|
||||||
SDRThreadIQDataQueue* pipeSDRIQData;
|
SDRThreadIQDataQueue* pipeSDRIQData;
|
||||||
DemodulatorThreadInputQueue* pipeIQVisualData;
|
DemodulatorThreadInputQueue* pipeIQVisualData;
|
||||||
DemodulatorThreadOutputQueue* pipeAudioVisualData;
|
DemodulatorThreadOutputQueue* pipeAudioVisualData;
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
#include "SDRDevices.h"
|
||||||
|
|
||||||
|
#include "SDRDevicesForm.h"
|
|
@ -0,0 +1,769 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||||
|
<wxFormBuilder_Project>
|
||||||
|
<FileVersion major="1" minor="13" />
|
||||||
|
<object class="Project" expanded="1">
|
||||||
|
<property name="class_decoration"></property>
|
||||||
|
<property name="code_generation">C++</property>
|
||||||
|
<property name="disconnect_events">1</property>
|
||||||
|
<property name="disconnect_mode">source_name</property>
|
||||||
|
<property name="disconnect_php_events">0</property>
|
||||||
|
<property name="disconnect_python_events">0</property>
|
||||||
|
<property name="embedded_files_path">res</property>
|
||||||
|
<property name="encoding">UTF-8</property>
|
||||||
|
<property name="event_generation">connect</property>
|
||||||
|
<property name="file">SDRDevicesForm</property>
|
||||||
|
<property name="first_id">1000</property>
|
||||||
|
<property name="help_provider">none</property>
|
||||||
|
<property name="internationalize">0</property>
|
||||||
|
<property name="name">SDRDevicesForm</property>
|
||||||
|
<property name="namespace"></property>
|
||||||
|
<property name="path">.</property>
|
||||||
|
<property name="precompiled_header"></property>
|
||||||
|
<property name="relative_path">1</property>
|
||||||
|
<property name="skip_lua_events">1</property>
|
||||||
|
<property name="skip_php_events">1</property>
|
||||||
|
<property name="skip_python_events">1</property>
|
||||||
|
<property name="ui_table">UI</property>
|
||||||
|
<property name="use_enum">0</property>
|
||||||
|
<property name="use_microsoft_bom">0</property>
|
||||||
|
<object class="Frame" expanded="1">
|
||||||
|
<property name="aui_managed">0</property>
|
||||||
|
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="center">wxBOTH</property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="event_handler">impl_virtual</property>
|
||||||
|
<property name="extra_style"></property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="name">devFrame</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="size">692,467</property>
|
||||||
|
<property name="style">wxDEFAULT_FRAME_STYLE</property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="title">CubicSDR :: SDR Devices</property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style">wxTAB_TRAVERSAL</property>
|
||||||
|
<property name="xrc_skip_sizer">1</property>
|
||||||
|
<event name="OnActivate"></event>
|
||||||
|
<event name="OnActivateApp"></event>
|
||||||
|
<event name="OnAuiFindManager"></event>
|
||||||
|
<event name="OnAuiPaneButton"></event>
|
||||||
|
<event name="OnAuiPaneClose"></event>
|
||||||
|
<event name="OnAuiPaneMaximize"></event>
|
||||||
|
<event name="OnAuiPaneRestore"></event>
|
||||||
|
<event name="OnAuiRender"></event>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnClose"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnHibernate"></event>
|
||||||
|
<event name="OnIconize"></event>
|
||||||
|
<event name="OnIdle"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
<object class="wxStatusBar" expanded="1">
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="fields">1</property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="name">devStatusBar</property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="size"></property>
|
||||||
|
<property name="style">wxST_SIZEGRIP</property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style"></property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
</object>
|
||||||
|
<object class="wxBoxSizer" expanded="1">
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="name">devFrameSizer</property>
|
||||||
|
<property name="orient">wxHORIZONTAL</property>
|
||||||
|
<property name="permission">none</property>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxEXPAND</property>
|
||||||
|
<property name="proportion">1</property>
|
||||||
|
<object class="wxTreeCtrl" expanded="1">
|
||||||
|
<property name="BottomDockable">1</property>
|
||||||
|
<property name="LeftDockable">1</property>
|
||||||
|
<property name="RightDockable">1</property>
|
||||||
|
<property name="TopDockable">1</property>
|
||||||
|
<property name="aui_layer"></property>
|
||||||
|
<property name="aui_name"></property>
|
||||||
|
<property name="aui_position"></property>
|
||||||
|
<property name="aui_row"></property>
|
||||||
|
<property name="best_size"></property>
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="caption"></property>
|
||||||
|
<property name="caption_visible">1</property>
|
||||||
|
<property name="center_pane">0</property>
|
||||||
|
<property name="close_button">1</property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="default_pane">0</property>
|
||||||
|
<property name="dock">Dock</property>
|
||||||
|
<property name="dock_fixed">0</property>
|
||||||
|
<property name="docking">Left</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="floatable">1</property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="gripper">0</property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="max_size"></property>
|
||||||
|
<property name="maximize_button">0</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="min_size"></property>
|
||||||
|
<property name="minimize_button">0</property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="moveable">1</property>
|
||||||
|
<property name="name">devTree</property>
|
||||||
|
<property name="pane_border">1</property>
|
||||||
|
<property name="pane_position"></property>
|
||||||
|
<property name="pane_size"></property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pin_button">1</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="resize">Resizable</property>
|
||||||
|
<property name="show">1</property>
|
||||||
|
<property name="size"></property>
|
||||||
|
<property name="style">wxTR_DEFAULT_STYLE</property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="toolbar_pane">0</property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style"></property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnTreeBeginDrag"></event>
|
||||||
|
<event name="OnTreeBeginLabelEdit"></event>
|
||||||
|
<event name="OnTreeBeginRDrag"></event>
|
||||||
|
<event name="OnTreeDeleteItem"></event>
|
||||||
|
<event name="OnTreeEndDrag"></event>
|
||||||
|
<event name="OnTreeEndLabelEdit"></event>
|
||||||
|
<event name="OnTreeGetInfo"></event>
|
||||||
|
<event name="OnTreeItemActivated"></event>
|
||||||
|
<event name="OnTreeItemCollapsed"></event>
|
||||||
|
<event name="OnTreeItemCollapsing"></event>
|
||||||
|
<event name="OnTreeItemExpanded"></event>
|
||||||
|
<event name="OnTreeItemExpanding"></event>
|
||||||
|
<event name="OnTreeItemGetTooltip"></event>
|
||||||
|
<event name="OnTreeItemMenu"></event>
|
||||||
|
<event name="OnTreeItemMiddleClick"></event>
|
||||||
|
<event name="OnTreeItemRightClick"></event>
|
||||||
|
<event name="OnTreeKeyDown"></event>
|
||||||
|
<event name="OnTreeSelChanged"></event>
|
||||||
|
<event name="OnTreeSelChanging"></event>
|
||||||
|
<event name="OnTreeSetInfo"></event>
|
||||||
|
<event name="OnTreeStateImageClick"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxEXPAND</property>
|
||||||
|
<property name="proportion">2</property>
|
||||||
|
<object class="wxNotebook" expanded="1">
|
||||||
|
<property name="BottomDockable">1</property>
|
||||||
|
<property name="LeftDockable">1</property>
|
||||||
|
<property name="RightDockable">1</property>
|
||||||
|
<property name="TopDockable">1</property>
|
||||||
|
<property name="aui_layer"></property>
|
||||||
|
<property name="aui_name"></property>
|
||||||
|
<property name="aui_position"></property>
|
||||||
|
<property name="aui_row"></property>
|
||||||
|
<property name="best_size"></property>
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="bitmapsize"></property>
|
||||||
|
<property name="caption"></property>
|
||||||
|
<property name="caption_visible">1</property>
|
||||||
|
<property name="center_pane">0</property>
|
||||||
|
<property name="close_button">1</property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="default_pane">0</property>
|
||||||
|
<property name="dock">Dock</property>
|
||||||
|
<property name="dock_fixed">0</property>
|
||||||
|
<property name="docking">Left</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="floatable">0</property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="gripper">0</property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="max_size"></property>
|
||||||
|
<property name="maximize_button">0</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="min_size"></property>
|
||||||
|
<property name="minimize_button">0</property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="moveable">1</property>
|
||||||
|
<property name="name">devTabs</property>
|
||||||
|
<property name="pane_border">1</property>
|
||||||
|
<property name="pane_position"></property>
|
||||||
|
<property name="pane_size"></property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pin_button">1</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="resize">Resizable</property>
|
||||||
|
<property name="show">1</property>
|
||||||
|
<property name="size"></property>
|
||||||
|
<property name="style"></property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="toolbar_pane">0</property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style"></property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnNotebookPageChanged"></event>
|
||||||
|
<event name="OnNotebookPageChanging"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
<object class="notebookpage" expanded="1">
|
||||||
|
<property name="bitmap"></property>
|
||||||
|
<property name="label">Device</property>
|
||||||
|
<property name="select">0</property>
|
||||||
|
<object class="wxPanel" expanded="1">
|
||||||
|
<property name="BottomDockable">1</property>
|
||||||
|
<property name="LeftDockable">1</property>
|
||||||
|
<property name="RightDockable">1</property>
|
||||||
|
<property name="TopDockable">1</property>
|
||||||
|
<property name="aui_layer"></property>
|
||||||
|
<property name="aui_name"></property>
|
||||||
|
<property name="aui_position"></property>
|
||||||
|
<property name="aui_row"></property>
|
||||||
|
<property name="best_size"></property>
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="caption"></property>
|
||||||
|
<property name="caption_visible">1</property>
|
||||||
|
<property name="center_pane">0</property>
|
||||||
|
<property name="close_button">1</property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="default_pane">0</property>
|
||||||
|
<property name="dock">Dock</property>
|
||||||
|
<property name="dock_fixed">0</property>
|
||||||
|
<property name="docking">Left</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="floatable">0</property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="gripper">0</property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="max_size"></property>
|
||||||
|
<property name="maximize_button">0</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="min_size"></property>
|
||||||
|
<property name="minimize_button">0</property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="moveable">1</property>
|
||||||
|
<property name="name">devInfoPanel</property>
|
||||||
|
<property name="pane_border">1</property>
|
||||||
|
<property name="pane_position"></property>
|
||||||
|
<property name="pane_size"></property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pin_button">1</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="resize">Resizable</property>
|
||||||
|
<property name="show">1</property>
|
||||||
|
<property name="size"></property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="toolbar_pane">0</property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style">wxTAB_TRAVERSAL</property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
<object class="wxBoxSizer" expanded="1">
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="name">devInfoSizer</property>
|
||||||
|
<property name="orient">wxVERTICAL</property>
|
||||||
|
<property name="permission">none</property>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxEXPAND</property>
|
||||||
|
<property name="proportion">1</property>
|
||||||
|
<object class="wxListCtrl" expanded="1">
|
||||||
|
<property name="BottomDockable">1</property>
|
||||||
|
<property name="LeftDockable">1</property>
|
||||||
|
<property name="RightDockable">1</property>
|
||||||
|
<property name="TopDockable">1</property>
|
||||||
|
<property name="aui_layer"></property>
|
||||||
|
<property name="aui_name"></property>
|
||||||
|
<property name="aui_position"></property>
|
||||||
|
<property name="aui_row"></property>
|
||||||
|
<property name="best_size"></property>
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="caption"></property>
|
||||||
|
<property name="caption_visible">1</property>
|
||||||
|
<property name="center_pane">0</property>
|
||||||
|
<property name="close_button">1</property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="default_pane">0</property>
|
||||||
|
<property name="dock">Dock</property>
|
||||||
|
<property name="dock_fixed">0</property>
|
||||||
|
<property name="docking">Left</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="floatable">1</property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="gripper">0</property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="max_size"></property>
|
||||||
|
<property name="maximize_button">0</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="min_size"></property>
|
||||||
|
<property name="minimize_button">0</property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="moveable">1</property>
|
||||||
|
<property name="name">m_DevInfoList</property>
|
||||||
|
<property name="pane_border">1</property>
|
||||||
|
<property name="pane_position"></property>
|
||||||
|
<property name="pane_size"></property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pin_button">1</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="resize">Resizable</property>
|
||||||
|
<property name="show">1</property>
|
||||||
|
<property name="size"></property>
|
||||||
|
<property name="style">wxLC_ICON</property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="toolbar_pane">0</property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="validator_data_type"></property>
|
||||||
|
<property name="validator_style">wxFILTER_NONE</property>
|
||||||
|
<property name="validator_type">wxDefaultValidator</property>
|
||||||
|
<property name="validator_variable"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style"></property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnListBeginDrag"></event>
|
||||||
|
<event name="OnListBeginLabelEdit"></event>
|
||||||
|
<event name="OnListBeginRDrag"></event>
|
||||||
|
<event name="OnListCacheHint"></event>
|
||||||
|
<event name="OnListColBeginDrag"></event>
|
||||||
|
<event name="OnListColClick"></event>
|
||||||
|
<event name="OnListColDragging"></event>
|
||||||
|
<event name="OnListColEndDrag"></event>
|
||||||
|
<event name="OnListColRightClick"></event>
|
||||||
|
<event name="OnListDeleteAllItems"></event>
|
||||||
|
<event name="OnListDeleteItem"></event>
|
||||||
|
<event name="OnListEndLabelEdit"></event>
|
||||||
|
<event name="OnListInsertItem"></event>
|
||||||
|
<event name="OnListItemActivated"></event>
|
||||||
|
<event name="OnListItemDeselected"></event>
|
||||||
|
<event name="OnListItemFocused"></event>
|
||||||
|
<event name="OnListItemMiddleClick"></event>
|
||||||
|
<event name="OnListItemRightClick"></event>
|
||||||
|
<event name="OnListItemSelected"></event>
|
||||||
|
<event name="OnListKeyDown"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="notebookpage" expanded="1">
|
||||||
|
<property name="bitmap"></property>
|
||||||
|
<property name="label">Parameters</property>
|
||||||
|
<property name="select">0</property>
|
||||||
|
<object class="wxPanel" expanded="1">
|
||||||
|
<property name="BottomDockable">1</property>
|
||||||
|
<property name="LeftDockable">1</property>
|
||||||
|
<property name="RightDockable">1</property>
|
||||||
|
<property name="TopDockable">1</property>
|
||||||
|
<property name="aui_layer"></property>
|
||||||
|
<property name="aui_name"></property>
|
||||||
|
<property name="aui_position"></property>
|
||||||
|
<property name="aui_row"></property>
|
||||||
|
<property name="best_size"></property>
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="caption"></property>
|
||||||
|
<property name="caption_visible">1</property>
|
||||||
|
<property name="center_pane">0</property>
|
||||||
|
<property name="close_button">1</property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="default_pane">0</property>
|
||||||
|
<property name="dock">Dock</property>
|
||||||
|
<property name="dock_fixed">0</property>
|
||||||
|
<property name="docking">Left</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="floatable">1</property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="gripper">0</property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="max_size"></property>
|
||||||
|
<property name="maximize_button">0</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="min_size"></property>
|
||||||
|
<property name="minimize_button">0</property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="moveable">1</property>
|
||||||
|
<property name="name">devParamsPanel</property>
|
||||||
|
<property name="pane_border">1</property>
|
||||||
|
<property name="pane_position"></property>
|
||||||
|
<property name="pane_size"></property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pin_button">1</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="resize">Resizable</property>
|
||||||
|
<property name="show">1</property>
|
||||||
|
<property name="size"></property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="toolbar_pane">0</property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style">wxTAB_TRAVERSAL</property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
<object class="wxBoxSizer" expanded="1">
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="name">devParamsSizer</property>
|
||||||
|
<property name="orient">wxVERTICAL</property>
|
||||||
|
<property name="permission">none</property>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxEXPAND</property>
|
||||||
|
<property name="proportion">1</property>
|
||||||
|
<object class="wxListCtrl" expanded="1">
|
||||||
|
<property name="BottomDockable">1</property>
|
||||||
|
<property name="LeftDockable">1</property>
|
||||||
|
<property name="RightDockable">1</property>
|
||||||
|
<property name="TopDockable">1</property>
|
||||||
|
<property name="aui_layer"></property>
|
||||||
|
<property name="aui_name"></property>
|
||||||
|
<property name="aui_position"></property>
|
||||||
|
<property name="aui_row"></property>
|
||||||
|
<property name="best_size"></property>
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="caption"></property>
|
||||||
|
<property name="caption_visible">1</property>
|
||||||
|
<property name="center_pane">0</property>
|
||||||
|
<property name="close_button">1</property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="default_pane">0</property>
|
||||||
|
<property name="dock">Dock</property>
|
||||||
|
<property name="dock_fixed">0</property>
|
||||||
|
<property name="docking">Left</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="floatable">1</property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="gripper">0</property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="max_size"></property>
|
||||||
|
<property name="maximize_button">0</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="min_size"></property>
|
||||||
|
<property name="minimize_button">0</property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="moveable">1</property>
|
||||||
|
<property name="name">m_ParamInfoList</property>
|
||||||
|
<property name="pane_border">1</property>
|
||||||
|
<property name="pane_position"></property>
|
||||||
|
<property name="pane_size"></property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pin_button">1</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="resize">Resizable</property>
|
||||||
|
<property name="show">1</property>
|
||||||
|
<property name="size"></property>
|
||||||
|
<property name="style">wxLC_ICON</property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="toolbar_pane">0</property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="validator_data_type"></property>
|
||||||
|
<property name="validator_style">wxFILTER_NONE</property>
|
||||||
|
<property name="validator_type">wxDefaultValidator</property>
|
||||||
|
<property name="validator_variable"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style"></property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnListBeginDrag"></event>
|
||||||
|
<event name="OnListBeginLabelEdit"></event>
|
||||||
|
<event name="OnListBeginRDrag"></event>
|
||||||
|
<event name="OnListCacheHint"></event>
|
||||||
|
<event name="OnListColBeginDrag"></event>
|
||||||
|
<event name="OnListColClick"></event>
|
||||||
|
<event name="OnListColDragging"></event>
|
||||||
|
<event name="OnListColEndDrag"></event>
|
||||||
|
<event name="OnListColRightClick"></event>
|
||||||
|
<event name="OnListDeleteAllItems"></event>
|
||||||
|
<event name="OnListDeleteItem"></event>
|
||||||
|
<event name="OnListEndLabelEdit"></event>
|
||||||
|
<event name="OnListInsertItem"></event>
|
||||||
|
<event name="OnListItemActivated"></event>
|
||||||
|
<event name="OnListItemDeselected"></event>
|
||||||
|
<event name="OnListItemFocused"></event>
|
||||||
|
<event name="OnListItemMiddleClick"></event>
|
||||||
|
<event name="OnListItemRightClick"></event>
|
||||||
|
<event name="OnListItemSelected"></event>
|
||||||
|
<event name="OnListKeyDown"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="wxMenuBar" expanded="1">
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="label">dMenu</property>
|
||||||
|
<property name="maximum_size"></property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="name">devMenuBar</property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
<property name="pos"></property>
|
||||||
|
<property name="size"></property>
|
||||||
|
<property name="style"></property>
|
||||||
|
<property name="subclass"></property>
|
||||||
|
<property name="tooltip"></property>
|
||||||
|
<property name="window_extra_style"></property>
|
||||||
|
<property name="window_name"></property>
|
||||||
|
<property name="window_style"></property>
|
||||||
|
<event name="OnChar"></event>
|
||||||
|
<event name="OnEnterWindow"></event>
|
||||||
|
<event name="OnEraseBackground"></event>
|
||||||
|
<event name="OnKeyDown"></event>
|
||||||
|
<event name="OnKeyUp"></event>
|
||||||
|
<event name="OnKillFocus"></event>
|
||||||
|
<event name="OnLeaveWindow"></event>
|
||||||
|
<event name="OnLeftDClick"></event>
|
||||||
|
<event name="OnLeftDown"></event>
|
||||||
|
<event name="OnLeftUp"></event>
|
||||||
|
<event name="OnMiddleDClick"></event>
|
||||||
|
<event name="OnMiddleDown"></event>
|
||||||
|
<event name="OnMiddleUp"></event>
|
||||||
|
<event name="OnMotion"></event>
|
||||||
|
<event name="OnMouseEvents"></event>
|
||||||
|
<event name="OnMouseWheel"></event>
|
||||||
|
<event name="OnPaint"></event>
|
||||||
|
<event name="OnRightDClick"></event>
|
||||||
|
<event name="OnRightDown"></event>
|
||||||
|
<event name="OnRightUp"></event>
|
||||||
|
<event name="OnSetFocus"></event>
|
||||||
|
<event name="OnSize"></event>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
<object class="wxMenu" expanded="1">
|
||||||
|
<property name="label">File</property>
|
||||||
|
<property name="name">devFileMenu</property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
</object>
|
||||||
|
<object class="wxMenu" expanded="1">
|
||||||
|
<property name="label">Edit</property>
|
||||||
|
<property name="name">devEditMenu</property>
|
||||||
|
<property name="permission">protected</property>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</wxFormBuilder_Project>
|
|
@ -0,0 +1 @@
|
||||||
|
#pragma once
|
|
@ -0,0 +1,69 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// C++ code generated with wxFormBuilder (version Aug 23 2015)
|
||||||
|
// http://www.wxformbuilder.org/
|
||||||
|
//
|
||||||
|
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "SDRDevicesForm.h"
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
devFrame::devFrame( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
|
||||||
|
{
|
||||||
|
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
|
||||||
|
|
||||||
|
devStatusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY );
|
||||||
|
wxBoxSizer* devFrameSizer;
|
||||||
|
devFrameSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||||
|
|
||||||
|
devTree = new wxTreeCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE );
|
||||||
|
devFrameSizer->Add( devTree, 1, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
devTabs = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
devInfoPanel = new wxPanel( devTabs, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||||
|
wxBoxSizer* devInfoSizer;
|
||||||
|
devInfoSizer = new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
|
m_DevInfoList = new wxListCtrl( devInfoPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_ICON );
|
||||||
|
devInfoSizer->Add( m_DevInfoList, 1, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
devInfoPanel->SetSizer( devInfoSizer );
|
||||||
|
devInfoPanel->Layout();
|
||||||
|
devInfoSizer->Fit( devInfoPanel );
|
||||||
|
devTabs->AddPage( devInfoPanel, wxT("Device"), false );
|
||||||
|
devParamsPanel = new wxPanel( devTabs, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||||
|
wxBoxSizer* devParamsSizer;
|
||||||
|
devParamsSizer = new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
|
m_ParamInfoList = new wxListCtrl( devParamsPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_ICON );
|
||||||
|
devParamsSizer->Add( m_ParamInfoList, 1, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
devParamsPanel->SetSizer( devParamsSizer );
|
||||||
|
devParamsPanel->Layout();
|
||||||
|
devParamsSizer->Fit( devParamsPanel );
|
||||||
|
devTabs->AddPage( devParamsPanel, wxT("Parameters"), false );
|
||||||
|
|
||||||
|
devFrameSizer->Add( devTabs, 2, wxEXPAND, 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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
devFrame::~devFrame()
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// C++ code generated with wxFormBuilder (version Aug 23 2015)
|
||||||
|
// http://www.wxformbuilder.org/
|
||||||
|
//
|
||||||
|
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef __SDRDEVICESFORM_H__
|
||||||
|
#define __SDRDEVICESFORM_H__
|
||||||
|
|
||||||
|
#include <wx/artprov.h>
|
||||||
|
#include <wx/xrc/xmlres.h>
|
||||||
|
#include <wx/statusbr.h>
|
||||||
|
#include <wx/gdicmn.h>
|
||||||
|
#include <wx/font.h>
|
||||||
|
#include <wx/colour.h>
|
||||||
|
#include <wx/settings.h>
|
||||||
|
#include <wx/string.h>
|
||||||
|
#include <wx/treectrl.h>
|
||||||
|
#include <wx/listctrl.h>
|
||||||
|
#include <wx/sizer.h>
|
||||||
|
#include <wx/panel.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>
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Class devFrame
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
class devFrame : public wxFrame
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
protected:
|
||||||
|
wxStatusBar* devStatusBar;
|
||||||
|
wxTreeCtrl* devTree;
|
||||||
|
wxNotebook* devTabs;
|
||||||
|
wxPanel* devInfoPanel;
|
||||||
|
wxListCtrl* m_DevInfoList;
|
||||||
|
wxPanel* devParamsPanel;
|
||||||
|
wxListCtrl* m_ParamInfoList;
|
||||||
|
wxMenuBar* devMenuBar;
|
||||||
|
wxMenu* devFileMenu;
|
||||||
|
wxMenu* devEditMenu;
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__SDRDEVICESFORM_H__
|
|
@ -4,10 +4,6 @@
|
||||||
#include "CubicSDR.h"
|
#include "CubicSDR.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <SoapySDR/Version.hpp>
|
|
||||||
#include <SoapySDR/Modules.hpp>
|
|
||||||
#include <SoapySDR/Registry.hpp>
|
|
||||||
#include <SoapySDR/Device.hpp>
|
|
||||||
|
|
||||||
std::vector<std::string> SDRThread::factories;
|
std::vector<std::string> SDRThread::factories;
|
||||||
std::vector<std::string> SDRThread::modules;
|
std::vector<std::string> SDRThread::modules;
|
||||||
|
@ -15,14 +11,32 @@ std::vector<SDRDeviceInfo *> SDRThread::devs;
|
||||||
|
|
||||||
|
|
||||||
SDRThread::SDRThread() : IOThread() {
|
SDRThread::SDRThread() : IOThread() {
|
||||||
offset.store(0);
|
device = NULL;
|
||||||
deviceId.store(-1);
|
|
||||||
// dev = NULL;
|
deviceConfig.store(NULL);
|
||||||
|
deviceInfo.store(NULL);
|
||||||
|
|
||||||
sampleRate.store(DEFAULT_SAMPLE_RATE);
|
sampleRate.store(DEFAULT_SAMPLE_RATE);
|
||||||
|
frequency.store(0);
|
||||||
|
offset.store(0);
|
||||||
|
ppm.store(0);
|
||||||
|
direct_sampling_mode.store(0);
|
||||||
|
|
||||||
|
numElems.store(0);
|
||||||
|
|
||||||
|
rate_changed.store(false);
|
||||||
|
freq_changed.store(false);
|
||||||
|
offset_changed.store(false);
|
||||||
|
ppm_changed .store(false);
|
||||||
|
direct_sampling_changed.store(false);
|
||||||
|
device_changed.store(false);
|
||||||
|
|
||||||
|
hasPPM.store(false);
|
||||||
|
hasHardwareDC.store(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDRThread::~SDRThread() {
|
SDRThread::~SDRThread() {
|
||||||
// rtlsdr_close(dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -145,6 +159,130 @@ std::vector<SDRDeviceInfo *> *SDRThread::enumerate_devices() {
|
||||||
return &SDRThread::devs;
|
return &SDRThread::devs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SDRThread::init() {
|
||||||
|
SDRDeviceInfo *devInfo = deviceInfo.load();
|
||||||
|
deviceConfig.store(wxGetApp().getConfig()->getDevice(devInfo->getDeviceId()));
|
||||||
|
DeviceConfig *devConfig = deviceConfig.load();
|
||||||
|
|
||||||
|
frequency = wxGetApp().getConfig()->getCenterFreq();
|
||||||
|
ppm.store(devConfig->getPPM());
|
||||||
|
direct_sampling_mode.store(devConfig->getDirectSampling());
|
||||||
|
|
||||||
|
std::string driverName = devInfo->getDriver();
|
||||||
|
|
||||||
|
offset = devConfig->getOffset();
|
||||||
|
wxGetApp().setSwapIQ(devConfig->getIQSwap());
|
||||||
|
|
||||||
|
SoapySDR::Kwargs args = devInfo->getDeviceArgs();
|
||||||
|
|
||||||
|
args["direct_samp"] = std::to_string(devConfig->getDirectSampling());
|
||||||
|
|
||||||
|
if (driverName == "rtl" || driverName == "rtlsdr") {
|
||||||
|
args["buffers"] = "6";
|
||||||
|
args["buflen"] = "16384";
|
||||||
|
hasPPM = true;
|
||||||
|
} else {
|
||||||
|
hasPPM = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
device = SoapySDR::Device::make(args);
|
||||||
|
stream = device->setupStream(SOAPY_SDR_RX,"CF32", std::vector<size_t>(), devInfo->getStreamArgs());
|
||||||
|
|
||||||
|
device->activateStream(stream);
|
||||||
|
device->setSampleRate(SOAPY_SDR_RX,0,sampleRate.load());
|
||||||
|
device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency - offset.load());
|
||||||
|
if (hasPPM) {
|
||||||
|
device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm);
|
||||||
|
}
|
||||||
|
device->setGainMode(SOAPY_SDR_RX,0,true);
|
||||||
|
hasHardwareDC = devInfo->hasHardwareDC();
|
||||||
|
|
||||||
|
numElems = getOptimalElementCount(sampleRate.load(), 60);
|
||||||
|
|
||||||
|
buffs[0] = malloc(numElems * 2 * sizeof(float));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRThread::deinit() {
|
||||||
|
device->deactivateStream(stream);
|
||||||
|
device->closeStream(stream);
|
||||||
|
SoapySDR::Device::unmake(device);
|
||||||
|
free(buffs[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRThread::readStream(SDRThreadIQDataQueue* iqDataOutQueue) {
|
||||||
|
int flags;
|
||||||
|
long long timeNs;
|
||||||
|
|
||||||
|
SDRThreadIQData *dataOut = buffers.getBuffer();
|
||||||
|
if (dataOut->data.size() != numElems * 2) {
|
||||||
|
dataOut->data.resize(numElems * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int n_read = 0;
|
||||||
|
while (n_read != numElems) {
|
||||||
|
int n_stream_read = device->readStream(stream, buffs, numElems-n_read, flags, timeNs);
|
||||||
|
if (n_stream_read > 0) {
|
||||||
|
memcpy(&dataOut->data[n_read * 2], buffs[0], n_stream_read * sizeof(float) * 2);
|
||||||
|
n_read += n_stream_read;
|
||||||
|
} else {
|
||||||
|
dataOut->data.resize(n_read);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// std::cout << n_read << std::endl;
|
||||||
|
|
||||||
|
if (n_read > 0) {
|
||||||
|
dataOut->setRefCount(1);
|
||||||
|
dataOut->frequency = frequency;
|
||||||
|
dataOut->sampleRate = sampleRate.load();
|
||||||
|
dataOut->dcCorrected = hasHardwareDC;
|
||||||
|
|
||||||
|
iqDataOutQueue->push(dataOut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRThread::readLoop() {
|
||||||
|
SDRThreadIQDataQueue* iqDataOutQueue = (SDRThreadIQDataQueue*) getOutputQueue("IQDataOutput");
|
||||||
|
|
||||||
|
if (iqDataOutQueue == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!terminated.load()) {
|
||||||
|
if (offset_changed.load()) {
|
||||||
|
if (!freq_changed.load()) {
|
||||||
|
frequency.store(frequency.load());
|
||||||
|
freq_changed.store(true);
|
||||||
|
}
|
||||||
|
offset_changed.store(false);
|
||||||
|
}
|
||||||
|
if (rate_changed.load()) {
|
||||||
|
device->setSampleRate(SOAPY_SDR_RX,0,sampleRate.load());
|
||||||
|
sampleRate.store(device->getSampleRate(SOAPY_SDR_RX,0));
|
||||||
|
numElems.store(getOptimalElementCount(sampleRate.load(), 60));
|
||||||
|
free(buffs[0]);
|
||||||
|
buffs[0] = malloc(numElems.load() * 2 * sizeof(float));
|
||||||
|
rate_changed.store(false);
|
||||||
|
}
|
||||||
|
if (ppm_changed.load() && hasPPM.load()) {
|
||||||
|
device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm.load());
|
||||||
|
direct_sampling_changed.store(false);
|
||||||
|
}
|
||||||
|
if (freq_changed.load()) {
|
||||||
|
device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency.load() - offset.load());
|
||||||
|
freq_changed.store(false);
|
||||||
|
}
|
||||||
|
if (direct_sampling_changed.load()) {
|
||||||
|
// rtlsdr_set_direct_sampling(dev, direct_sampling_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
readStream(iqDataOutQueue);
|
||||||
|
}
|
||||||
|
buffers.purge();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SDRThread::run() {
|
void SDRThread::run() {
|
||||||
//#ifdef __APPLE__
|
//#ifdef __APPLE__
|
||||||
// pthread_t tID = pthread_self(); // ID of this thread
|
// pthread_t tID = pthread_self(); // ID of this thread
|
||||||
|
@ -153,242 +291,98 @@ void SDRThread::run() {
|
||||||
// pthread_setschedparam(tID, SCHED_FIFO, &prio);
|
// pthread_setschedparam(tID, SCHED_FIFO, &prio);
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
std::cout << "SDR thread initializing.." << std::endl;
|
std::cout << "SDR thread starting." << std::endl;
|
||||||
|
terminated.store(false);
|
||||||
|
|
||||||
if (deviceId == -1 && devs.size() == 0) {
|
if (deviceInfo.load() != NULL) {
|
||||||
std::cout << "No devices found.. SDR Thread exiting.." << std::endl;
|
std::cout << "device init()" << std::endl;
|
||||||
return;
|
init();
|
||||||
|
std::cout << "starting readLoop()" << std::endl;
|
||||||
|
readLoop();
|
||||||
|
std::cout << "readLoop() ended." << std::endl;
|
||||||
|
deinit();
|
||||||
|
std::cout << "device deinit()" << std::endl;
|
||||||
} else {
|
} else {
|
||||||
if (deviceId == -1) {
|
std::cout << "Device setting not found, enumerating." << std::endl;
|
||||||
deviceId = 0;
|
SDRThread::enumerate_devices();
|
||||||
}
|
std::cout << "Reporting enumeration complete." << std::endl;
|
||||||
std::cout << "Using device #" << deviceId << std::endl;
|
wxGetApp().sdrThreadNotify(SDRThread::SDR_THREAD_DEVICES_READY, "Devices Ready.");
|
||||||
}
|
terminated.store(true);
|
||||||
|
return;
|
||||||
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(devs[deviceId]->getDeviceId());
|
|
||||||
|
|
||||||
long long frequency = wxGetApp().getConfig()->getCenterFreq();
|
|
||||||
int ppm = devConfig->getPPM();
|
|
||||||
int direct_sampling_mode = devConfig->getDirectSampling();
|
|
||||||
int numElems = 0;
|
|
||||||
bool hasPPM = false;
|
|
||||||
bool hasHardwareDC = false;
|
|
||||||
|
|
||||||
offset.store(devConfig->getOffset());
|
|
||||||
wxGetApp().setSwapIQ(devConfig->getIQSwap());
|
|
||||||
|
|
||||||
|
|
||||||
SDRDeviceInfo *dev = devs[deviceId];
|
|
||||||
SoapySDR::Kwargs args = dev->getDeviceArgs();
|
|
||||||
|
|
||||||
std::string driverName = dev->getDriver();
|
|
||||||
|
|
||||||
if (driverName == "rtl" || driverName == "rtlsdr") {
|
|
||||||
hasPPM = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
args["direct_samp"] = std::to_string(devConfig->getDirectSampling());
|
|
||||||
args["buffers"] = "6";
|
|
||||||
args["buflen"] = "16384";
|
|
||||||
SoapySDR::Device *device = SoapySDR::Device::make(args);
|
|
||||||
|
|
||||||
SoapySDR::Stream *stream = device->setupStream(SOAPY_SDR_RX,"CF32", std::vector<size_t>(), dev->getStreamArgs());
|
|
||||||
|
|
||||||
device->activateStream(stream);
|
|
||||||
device->setSampleRate(SOAPY_SDR_RX,0,sampleRate.load());
|
|
||||||
device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency - offset.load());
|
|
||||||
if (hasPPM) {
|
|
||||||
device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm);
|
|
||||||
}
|
|
||||||
|
|
||||||
device->setGainMode(SOAPY_SDR_RX,0,true);
|
|
||||||
hasHardwareDC = dev->hasHardwareDC();
|
|
||||||
|
|
||||||
numElems = getOptimalElementCount(sampleRate.load(), 60);
|
|
||||||
|
|
||||||
void *buffs[1];
|
|
||||||
buffs[0] = malloc(numElems * 2 * sizeof(float));
|
|
||||||
|
|
||||||
int flags;
|
|
||||||
long long timeNs;
|
|
||||||
|
|
||||||
ReBuffer<SDRThreadIQData> buffers;
|
|
||||||
|
|
||||||
SDRThreadIQDataQueue* iqDataOutQueue = (SDRThreadIQDataQueue*) getOutputQueue("IQDataOutput");
|
|
||||||
SDRThreadCommandQueue* cmdQueue = (SDRThreadCommandQueue*) getInputQueue("SDRCommandQueue");
|
|
||||||
|
|
||||||
while (!terminated) {
|
|
||||||
if (!cmdQueue->empty()) {
|
|
||||||
bool freq_changed = false;
|
|
||||||
bool offset_changed = false;
|
|
||||||
bool rate_changed = false;
|
|
||||||
bool device_changed = false;
|
|
||||||
bool ppm_changed = false;
|
|
||||||
bool direct_sampling_changed = false;
|
|
||||||
long long new_freq = frequency;
|
|
||||||
long long new_offset = offset.load();
|
|
||||||
long long new_rate = sampleRate.load();
|
|
||||||
int new_device = deviceId;
|
|
||||||
int new_ppm = ppm;
|
|
||||||
|
|
||||||
while (!cmdQueue->empty()) {
|
|
||||||
SDRThreadCommand command;
|
|
||||||
cmdQueue->pop(command);
|
|
||||||
|
|
||||||
switch (command.cmd) {
|
|
||||||
case SDRThreadCommand::SDR_THREAD_CMD_TUNE:
|
|
||||||
freq_changed = true;
|
|
||||||
new_freq = command.llong_value;
|
|
||||||
if (new_freq < sampleRate.load() / 2) {
|
|
||||||
new_freq = sampleRate.load() / 2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SDRThreadCommand::SDR_THREAD_CMD_SET_OFFSET:
|
|
||||||
offset_changed = true;
|
|
||||||
new_offset = command.llong_value;
|
|
||||||
std::cout << "Set offset: " << new_offset << std::endl;
|
|
||||||
break;
|
|
||||||
case SDRThreadCommand::SDR_THREAD_CMD_SET_SAMPLERATE:
|
|
||||||
rate_changed = true;
|
|
||||||
new_rate = command.llong_value;
|
|
||||||
std::cout << "Set sample rate: " << new_rate << std::endl;
|
|
||||||
break;
|
|
||||||
case SDRThreadCommand::SDR_THREAD_CMD_SET_DEVICE:
|
|
||||||
device_changed = true;
|
|
||||||
new_device = (int) command.llong_value;
|
|
||||||
std::cout << "Set device: " << new_device << std::endl;
|
|
||||||
break;
|
|
||||||
case SDRThreadCommand::SDR_THREAD_CMD_SET_PPM:
|
|
||||||
ppm_changed = true;
|
|
||||||
new_ppm = (int) command.llong_value;
|
|
||||||
//std::cout << "Set PPM: " << new_ppm << std::endl;
|
|
||||||
break;
|
|
||||||
case SDRThreadCommand::SDR_THREAD_CMD_SET_DIRECT_SAMPLING:
|
|
||||||
direct_sampling_mode = (int)command.llong_value;
|
|
||||||
direct_sampling_changed = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device_changed) {
|
|
||||||
device->deactivateStream(stream);
|
|
||||||
device->closeStream(stream);
|
|
||||||
SoapySDR::Device::unmake(device);
|
|
||||||
|
|
||||||
deviceId = new_device;
|
|
||||||
dev = devs[deviceId];
|
|
||||||
device_changed = false;
|
|
||||||
|
|
||||||
SoapySDR::Kwargs args = dev->getDeviceArgs();
|
|
||||||
args["direct_samp"] = std::to_string(devConfig->getDirectSampling());
|
|
||||||
args["buffers"] = "6";
|
|
||||||
args["buflen"] = "16384";
|
|
||||||
|
|
||||||
device = SoapySDR::Device::make(args);
|
|
||||||
|
|
||||||
device->setSampleRate(SOAPY_SDR_RX,0,sampleRate.load());
|
|
||||||
device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency - offset.load());
|
|
||||||
if (hasPPM) {
|
|
||||||
device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm);
|
|
||||||
}
|
|
||||||
device->setGainMode(SOAPY_SDR_RX,0, true);
|
|
||||||
hasHardwareDC = dev->hasHardwareDC();
|
|
||||||
if (hasHardwareDC) {
|
|
||||||
device->setDCOffsetMode(SOAPY_SDR_RX, 0, true);
|
|
||||||
std::cout << "Hardware DC offset support detected; internal DC offset compensation disabled." << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
SoapySDR::Stream *stream = device->setupStream(SOAPY_SDR_RX,"CF32", std::vector<size_t>(), dev->getStreamArgs());
|
|
||||||
device->activateStream(stream);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset_changed) {
|
|
||||||
if (!freq_changed) {
|
|
||||||
new_freq = frequency;
|
|
||||||
freq_changed = true;
|
|
||||||
}
|
|
||||||
offset.store(new_offset);
|
|
||||||
}
|
|
||||||
if (rate_changed) {
|
|
||||||
device->setSampleRate(SOAPY_SDR_RX,0,new_rate);
|
|
||||||
sampleRate.store(device->getSampleRate(SOAPY_SDR_RX,0));
|
|
||||||
|
|
||||||
numElems = getOptimalElementCount(sampleRate.load(), 60);
|
|
||||||
free(buffs[0]);
|
|
||||||
buffs[0] = malloc(numElems * 2 * sizeof(float));
|
|
||||||
}
|
|
||||||
if (freq_changed) {
|
|
||||||
frequency = new_freq;
|
|
||||||
device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency - offset.load());
|
|
||||||
}
|
|
||||||
if (ppm_changed && hasPPM) {
|
|
||||||
ppm = new_ppm;
|
|
||||||
device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm);
|
|
||||||
}
|
|
||||||
if (direct_sampling_changed) {
|
|
||||||
// rtlsdr_set_direct_sampling(dev, direct_sampling_mode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SDRThreadIQData *dataOut = buffers.getBuffer();
|
|
||||||
if (dataOut->data.size() != numElems * 2) {
|
|
||||||
dataOut->data.resize(numElems * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
int n_read = 0;
|
|
||||||
while (n_read != numElems) {
|
|
||||||
int n_stream_read = device->readStream(stream, buffs, numElems-n_read, flags, timeNs);
|
|
||||||
if (n_stream_read > 0) {
|
|
||||||
memcpy(&dataOut->data[n_read * 2], buffs[0], n_stream_read * sizeof(float) * 2);
|
|
||||||
n_read += n_stream_read;
|
|
||||||
} else {
|
|
||||||
dataOut->data.resize(n_read);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// std::cout << n_read << std::endl;
|
|
||||||
|
|
||||||
if (n_read > 0) {
|
|
||||||
dataOut->setRefCount(1);
|
|
||||||
dataOut->frequency = frequency;
|
|
||||||
dataOut->sampleRate = sampleRate.load();
|
|
||||||
dataOut->dcCorrected = hasHardwareDC;
|
|
||||||
|
|
||||||
if (iqDataOutQueue != NULL) {
|
|
||||||
iqDataOutQueue->push(dataOut);
|
|
||||||
} else {
|
|
||||||
dataOut->setRefCount(0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dataOut->setRefCount(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
device->deactivateStream(stream);
|
|
||||||
device->closeStream(stream);
|
|
||||||
SoapySDR::Device::unmake(device);
|
|
||||||
free(buffs[0]);
|
|
||||||
|
|
||||||
buffers.purge();
|
|
||||||
std::cout << "SDR thread done." << std::endl;
|
std::cout << "SDR thread done." << std::endl;
|
||||||
|
|
||||||
|
if (!terminated.load()) {
|
||||||
|
terminated.store(true);
|
||||||
|
wxGetApp().sdrThreadNotify(SDRThread::SDR_THREAD_TERMINATED, "Done.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int SDRThread::getDeviceId() const {
|
SDRDeviceInfo *SDRThread::getDevice() {
|
||||||
return deviceId.load();
|
return deviceInfo.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDRThread::setDeviceId(int deviceId) {
|
void SDRThread::setDevice(SDRDeviceInfo *dev) {
|
||||||
this->deviceId.store(deviceId);
|
deviceInfo.store(dev);
|
||||||
|
deviceConfig.store(wxGetApp().getConfig()->getDevice(dev->getDeviceId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDRThread::getOptimalElementCount(long long sampleRate, int fps) {
|
int SDRThread::getOptimalElementCount(long long sampleRate, int fps) {
|
||||||
int elemCount = (int)floor((double)sampleRate/(double)fps);
|
int elemCount = (int)floor((double)sampleRate/(double)fps);
|
||||||
elemCount = int(ceil((double)elemCount/512.0)*512.0);
|
elemCount = int(ceil((double)elemCount/512.0)*512.0);
|
||||||
std::cout << "calculated optimal element count of " << elemCount << std::endl;
|
std::cout << "Calculated optimal element count of " << elemCount << std::endl;
|
||||||
return elemCount;
|
return elemCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SDRThread::setFrequency(long long freq) {
|
||||||
|
if (freq < sampleRate.load() / 2) {
|
||||||
|
freq = sampleRate.load() / 2;
|
||||||
|
}
|
||||||
|
frequency.store(freq);
|
||||||
|
freq_changed.store(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
long long SDRThread::getFrequency() {
|
||||||
|
return frequency.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRThread::setOffset(long long ofs) {
|
||||||
|
offset.store(ofs);
|
||||||
|
offset_changed.store(true);
|
||||||
|
std::cout << "Set offset: " << offset.load() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long SDRThread::getOffset() {
|
||||||
|
return offset.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRThread::setSampleRate(int rate) {
|
||||||
|
sampleRate.store(rate);
|
||||||
|
rate_changed = true;
|
||||||
|
std::cout << "Set sample rate: " << sampleRate.load() << std::endl;
|
||||||
|
}
|
||||||
|
int SDRThread::getSampleRate() {
|
||||||
|
return sampleRate.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRThread::setPPM(int ppm) {
|
||||||
|
this->ppm.store(ppm);
|
||||||
|
ppm_changed.store(true);
|
||||||
|
std::cout << "Set PPM: " << this->ppm.load() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SDRThread::getPPM() {
|
||||||
|
return ppm.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRThread::setDirectSampling(int dsMode) {
|
||||||
|
direct_sampling_mode.store(dsMode);
|
||||||
|
direct_sampling_changed.store(true);
|
||||||
|
std::cout << "Set direct sampling mode: " << this->direct_sampling_mode.load() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SDRThread::getDirectSampling() {
|
||||||
|
return direct_sampling_mode.load();
|
||||||
|
}
|
||||||
|
|
|
@ -5,33 +5,19 @@
|
||||||
#include "ThreadQueue.h"
|
#include "ThreadQueue.h"
|
||||||
#include "DemodulatorMgr.h"
|
#include "DemodulatorMgr.h"
|
||||||
#include "SDRDeviceInfo.h"
|
#include "SDRDeviceInfo.h"
|
||||||
|
#include "AppConfig.h"
|
||||||
|
|
||||||
class SDRThreadCommand {
|
#include <SoapySDR/Version.hpp>
|
||||||
public:
|
#include <SoapySDR/Modules.hpp>
|
||||||
enum SDRThreadCommandEnum {
|
#include <SoapySDR/Registry.hpp>
|
||||||
SDR_THREAD_CMD_NULL, SDR_THREAD_CMD_TUNE, SDR_THREAD_CMD_SET_OFFSET, SDR_THREAD_CMD_SET_SAMPLERATE, SDR_THREAD_CMD_SET_PPM, SDR_THREAD_CMD_SET_DEVICE, SDR_THREAD_CMD_SET_DIRECT_SAMPLING
|
#include <SoapySDR/Device.hpp>
|
||||||
};
|
|
||||||
|
|
||||||
SDRThreadCommand() :
|
|
||||||
cmd(SDR_THREAD_CMD_NULL), llong_value(0) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
SDRThreadCommand(SDRThreadCommandEnum cmd) :
|
|
||||||
cmd(cmd), llong_value(0) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
SDRThreadCommandEnum cmd;
|
|
||||||
long long llong_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SDRThreadIQData: public ReferenceCounter {
|
class SDRThreadIQData: public ReferenceCounter {
|
||||||
public:
|
public:
|
||||||
long long frequency;
|
long long frequency;
|
||||||
long long sampleRate;
|
long long sampleRate;
|
||||||
bool dcCorrected;
|
bool dcCorrected;
|
||||||
// std::vector<unsigned char> data;
|
|
||||||
std::vector<float> data;
|
std::vector<float> data;
|
||||||
|
|
||||||
SDRThreadIQData() :
|
SDRThreadIQData() :
|
||||||
|
@ -49,27 +35,60 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ThreadQueue<SDRThreadCommand> SDRThreadCommandQueue;
|
|
||||||
typedef ThreadQueue<SDRThreadIQData *> SDRThreadIQDataQueue;
|
typedef ThreadQueue<SDRThreadIQData *> SDRThreadIQDataQueue;
|
||||||
|
|
||||||
class SDRThread : public IOThread {
|
class SDRThread : public IOThread {
|
||||||
|
private:
|
||||||
|
void init();
|
||||||
|
void deinit();
|
||||||
|
void readStream(SDRThreadIQDataQueue* iqDataOutQueue);
|
||||||
|
void readLoop();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SDRThread();
|
SDRThread();
|
||||||
~SDRThread();
|
~SDRThread();
|
||||||
|
enum SDRThreadState { SDR_THREAD_DEVICES_READY, SDR_THREAD_NO_DEVICES, SDR_THREAD_TERMINATED, SDR_THREAD_FAILED };
|
||||||
|
|
||||||
static std::vector<SDRDeviceInfo *> *enumerate_devices();
|
static std::vector<SDRDeviceInfo *> *enumerate_devices();
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
int getDeviceId() const;
|
|
||||||
void setDeviceId(int deviceId);
|
|
||||||
int getOptimalElementCount(long long sampleRate, int fps);
|
|
||||||
|
|
||||||
|
SDRDeviceInfo *getDevice();
|
||||||
|
void setDevice(SDRDeviceInfo *dev);
|
||||||
|
int getOptimalElementCount(long long sampleRate, int fps);
|
||||||
|
|
||||||
|
void setFrequency(long long freq);
|
||||||
|
long long getFrequency();
|
||||||
|
|
||||||
|
void setOffset(long long ofs);
|
||||||
|
long long getOffset();
|
||||||
|
|
||||||
|
void setSampleRate(int rate);
|
||||||
|
int getSampleRate();
|
||||||
|
|
||||||
|
void setPPM(int ppm);
|
||||||
|
int getPPM();
|
||||||
|
|
||||||
|
void setDirectSampling(int dsMode);
|
||||||
|
int getDirectSampling();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
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<SDRDeviceInfo *> devs;
|
||||||
|
SoapySDR::Stream *stream;
|
||||||
|
SoapySDR::Device *device;
|
||||||
|
void *buffs[1];
|
||||||
|
ReBuffer<SDRThreadIQData> buffers;
|
||||||
|
|
||||||
|
std::atomic<DeviceConfig *> deviceConfig;
|
||||||
|
std::atomic<SDRDeviceInfo *> deviceInfo;
|
||||||
|
|
||||||
std::atomic<uint32_t> sampleRate;
|
std::atomic<uint32_t> sampleRate;
|
||||||
std::atomic_llong offset;
|
std::atomic_llong frequency, offset;
|
||||||
std::atomic_int deviceId;
|
std::atomic_int ppm, direct_sampling_mode, numElems;
|
||||||
|
std::atomic_bool hasPPM, hasHardwareDC;
|
||||||
|
|
||||||
|
std::atomic_bool rate_changed, freq_changed, offset_changed,
|
||||||
|
ppm_changed, direct_sampling_changed, device_changed;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue