2014-10-27 20:05:40 -04:00
|
|
|
#define OPENGL
|
|
|
|
|
2015-02-17 21:26:14 -05:00
|
|
|
#include "CubicSDRDefs.h"
|
2014-10-27 20:05:40 -04:00
|
|
|
#include "wx/wxprec.h"
|
|
|
|
|
|
|
|
#ifndef WX_PRECOMP
|
|
|
|
#include "wx/wx.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if !wxUSE_GLCANVAS
|
|
|
|
#error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
|
|
|
|
#endif
|
|
|
|
|
2014-10-27 21:22:29 -04:00
|
|
|
#include "CubicSDR.h"
|
2015-10-20 23:00:10 -04:00
|
|
|
#include <iomanip>
|
2014-10-27 20:05:40 -04:00
|
|
|
|
2015-02-17 21:26:14 -05:00
|
|
|
#ifdef _OSX_APP_
|
|
|
|
#include "CoreFoundation/CoreFoundation.h"
|
|
|
|
#endif
|
|
|
|
|
2016-01-03 19:00:26 -05:00
|
|
|
#ifdef USE_HAMLIB
|
|
|
|
#include "RigThread.h"
|
|
|
|
#endif
|
|
|
|
|
2014-10-27 20:05:40 -04:00
|
|
|
IMPLEMENT_APP(CubicSDR)
|
|
|
|
|
2016-06-09 13:21:43 -04:00
|
|
|
#include <fstream>
|
2016-06-19 10:45:40 -04:00
|
|
|
#include <clocale>
|
2016-06-09 13:21:43 -04:00
|
|
|
|
2015-11-28 23:03:07 -05:00
|
|
|
//#ifdef ENABLE_DIGITAL_LAB
|
|
|
|
//// console output buffer for windows
|
|
|
|
//#ifdef _WINDOWS
|
|
|
|
//class outbuf : public std::streambuf {
|
|
|
|
// public:
|
|
|
|
// outbuf() {
|
|
|
|
// setp(0, 0);
|
|
|
|
// }
|
|
|
|
// virtual int_type overflow(int_type c = traits_type::eof()) {
|
|
|
|
// return fputc(c, stdout) == EOF ? traits_type::eof() : c;
|
|
|
|
// }
|
|
|
|
//};
|
|
|
|
//#endif
|
|
|
|
//#endif
|
2015-06-10 14:48:05 -04:00
|
|
|
|
2015-10-19 23:02:50 -04:00
|
|
|
#ifdef MINGW_PATCH
|
|
|
|
FILE _iob[] = { *stdin, *stdout, *stderr };
|
2015-07-30 21:53:29 -04:00
|
|
|
|
2015-10-19 23:02:50 -04:00
|
|
|
extern "C" FILE * __cdecl __iob_func(void)
|
|
|
|
{
|
|
|
|
return _iob;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" int __cdecl __isnan(double x)
|
|
|
|
{
|
|
|
|
return _finite(x)?0:1;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" int __cdecl __isnanf(float x)
|
|
|
|
{
|
|
|
|
return _finitef(x)?0:1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-10-20 23:00:10 -04:00
|
|
|
|
|
|
|
std::string& filterChars(std::string& s, const std::string& allowed) {
|
|
|
|
s.erase(remove_if(s.begin(), s.end(), [&allowed](const char& c) {
|
|
|
|
return allowed.find(c) == std::string::npos;
|
|
|
|
}), s.end());
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string frequencyToStr(long long freq) {
|
|
|
|
long double freqTemp;
|
|
|
|
|
|
|
|
freqTemp = freq;
|
|
|
|
std::string suffix("");
|
|
|
|
std::stringstream freqStr;
|
2015-07-27 21:45:24 -04:00
|
|
|
|
2015-10-20 23:00:10 -04:00
|
|
|
if (freqTemp >= 1.0e9) {
|
|
|
|
freqTemp /= 1.0e9;
|
|
|
|
freqStr << std::setprecision(10);
|
|
|
|
suffix = std::string("GHz");
|
|
|
|
} else if (freqTemp >= 1.0e6) {
|
|
|
|
freqTemp /= 1.0e6;
|
|
|
|
freqStr << std::setprecision(7);
|
|
|
|
suffix = std::string("MHz");
|
|
|
|
} else if (freqTemp >= 1.0e3) {
|
|
|
|
freqTemp /= 1.0e3;
|
|
|
|
freqStr << std::setprecision(4);
|
|
|
|
suffix = std::string("KHz");
|
|
|
|
}
|
|
|
|
|
|
|
|
freqStr << freqTemp;
|
|
|
|
freqStr << suffix;
|
|
|
|
|
|
|
|
return freqStr.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
long long strToFrequency(std::string freqStr) {
|
|
|
|
std::string filterStr = filterChars(freqStr, std::string("0123456789.MKGHmkgh"));
|
|
|
|
|
2016-01-28 15:49:31 -05:00
|
|
|
size_t numLen = filterStr.find_first_not_of("0123456789.");
|
2015-10-20 23:00:10 -04:00
|
|
|
|
|
|
|
if (numLen == std::string::npos) {
|
|
|
|
numLen = freqStr.length();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string numPartStr = freqStr.substr(0, numLen);
|
|
|
|
std::string suffixStr = freqStr.substr(numLen);
|
|
|
|
|
|
|
|
std::stringstream numPartStream;
|
|
|
|
numPartStream.str(numPartStr);
|
|
|
|
|
|
|
|
long double freqTemp = 0;
|
|
|
|
|
|
|
|
numPartStream >> freqTemp;
|
|
|
|
|
|
|
|
if (suffixStr.length()) {
|
|
|
|
if (suffixStr.find_first_of("Gg") != std::string::npos) {
|
|
|
|
freqTemp *= 1.0e9;
|
|
|
|
} else if (suffixStr.find_first_of("Mm") != std::string::npos) {
|
|
|
|
freqTemp *= 1.0e6;
|
|
|
|
} else if (suffixStr.find_first_of("Kk") != std::string::npos) {
|
|
|
|
freqTemp *= 1.0e3;
|
|
|
|
} else if (suffixStr.find_first_of("Hh") != std::string::npos) {
|
|
|
|
// ...
|
|
|
|
}
|
|
|
|
} else if (numPartStr.find_first_of(".") != std::string::npos || freqTemp <= 3000) {
|
|
|
|
freqTemp *= 1.0e6;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (long long) freqTemp;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-07-05 15:43:45 -04:00
|
|
|
CubicSDR::CubicSDR() : frequency(0), offset(0), ppm(0), snap(1), sampleRate(DEFAULT_SAMPLE_RATE),agcMode(false)
|
|
|
|
{
|
2015-10-21 16:56:32 -04:00
|
|
|
sampleRateInitialized.store(false);
|
2015-10-27 01:56:49 -04:00
|
|
|
agcMode.store(true);
|
2016-02-11 01:09:15 -05:00
|
|
|
soloMode.store(false);
|
2016-02-07 21:05:49 -05:00
|
|
|
fdlgTarget = FrequencyDialog::FDIALOG_TARGET_DEFAULT;
|
2016-02-28 23:16:56 -05:00
|
|
|
stoppedDev = nullptr;
|
2015-07-27 21:45:24 -04:00
|
|
|
}
|
|
|
|
|
2014-10-27 20:05:40 -04:00
|
|
|
bool CubicSDR::OnInit() {
|
2016-06-19 10:45:40 -04:00
|
|
|
|
|
|
|
//use the current locale most appropriate to this system,
|
|
|
|
//so that character-related functions are likely to handle Unicode
|
|
|
|
//better (by default, was "C" locale).
|
|
|
|
std::setlocale(LC_ALL, "");
|
|
|
|
|
2016-06-28 19:36:37 -04:00
|
|
|
//#ifdef _OSX_APP_
|
|
|
|
// CFBundleRef mainBundle = CFBundleGetMainBundle();
|
|
|
|
// CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
|
|
|
|
// char path[PATH_MAX];
|
|
|
|
// if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, PATH_MAX))
|
|
|
|
// {
|
|
|
|
// // error!
|
|
|
|
// }
|
|
|
|
// CFRelease(resourcesURL);
|
|
|
|
// chdir(path);
|
|
|
|
//#endif
|
2015-04-13 21:18:45 -04:00
|
|
|
|
2015-04-13 19:58:34 -04:00
|
|
|
if (!wxApp::OnInit()) {
|
2014-10-27 20:05:40 -04:00
|
|
|
return false;
|
2015-04-13 19:58:34 -04:00
|
|
|
}
|
|
|
|
|
2016-08-13 15:31:21 -04:00
|
|
|
//Deactivated code to allocate an explicit Console on Windows.
|
|
|
|
//This tends to hang the apllication on heavy demod (re)creation.
|
|
|
|
//To continue to debug with std::cout traces, simply run CubicSDR in a MINSYS2 compatble shell on Windows:
|
|
|
|
//ex: Cygwin shell, Git For Windows Bash shell....
|
|
|
|
#if (0)
|
2016-06-09 13:21:43 -04:00
|
|
|
if (AllocConsole()) {
|
|
|
|
freopen("CONOUT$", "w", stdout);
|
|
|
|
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);
|
|
|
|
SetConsoleTitle(L"CubicSDR: stdout");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//refresh
|
|
|
|
ofstream ob;
|
|
|
|
std::streambuf *sb = std::cout.rdbuf();
|
|
|
|
std::cout.rdbuf(sb);
|
|
|
|
#endif
|
2016-06-19 10:45:40 -04:00
|
|
|
|
2015-11-15 13:52:54 -05:00
|
|
|
|
2015-04-21 23:19:45 -04:00
|
|
|
wxApp::SetAppName("CubicSDR");
|
2015-04-13 19:58:34 -04:00
|
|
|
|
2016-01-03 19:00:26 -05:00
|
|
|
#ifdef USE_HAMLIB
|
|
|
|
t_Rig = nullptr;
|
|
|
|
rigThread = nullptr;
|
|
|
|
|
|
|
|
RigThread::enumerate();
|
|
|
|
#endif
|
|
|
|
|
2016-07-24 15:25:17 -04:00
|
|
|
Modem::addModemFactory(ModemFM::factory, "FM", 200000);
|
|
|
|
Modem::addModemFactory(ModemNBFM::factory, "NBFM", 12500);
|
|
|
|
Modem::addModemFactory(ModemFMStereo::factory, "FMS", 200000);
|
|
|
|
Modem::addModemFactory(ModemAM::factory, "AM", 6000);
|
|
|
|
Modem::addModemFactory(ModemLSB::factory, "LSB", 5400);
|
|
|
|
Modem::addModemFactory(ModemUSB::factory, "USB", 5400);
|
|
|
|
Modem::addModemFactory(ModemDSB::factory, "DSB", 5400);
|
|
|
|
Modem::addModemFactory(ModemIQ::factory, "I/Q", 48000);
|
2015-11-18 23:40:30 -05:00
|
|
|
|
2015-11-22 19:56:25 -05:00
|
|
|
#ifdef ENABLE_DIGITAL_LAB
|
2016-07-24 15:25:17 -04:00
|
|
|
Modem::addModemFactory(ModemAPSK::factory, "APSK", 200000);
|
|
|
|
Modem::addModemFactory(ModemASK::factory, "ASK", 200000);
|
|
|
|
Modem::addModemFactory(ModemBPSK::factory, "BPSK", 200000);
|
|
|
|
Modem::addModemFactory(ModemDPSK::factory, "DPSK", 200000);
|
2015-12-01 22:06:50 -05:00
|
|
|
#if ENABLE_LIQUID_EXPERIMENTAL
|
2016-07-24 15:25:17 -04:00
|
|
|
Modem::addModemFactory(ModemFSK::factory, "FSK", 19200);
|
2015-12-01 22:06:50 -05:00
|
|
|
#endif
|
2016-07-24 15:25:17 -04:00
|
|
|
Modem::addModemFactory(ModemGMSK::factory, "GMSK", 19200);
|
|
|
|
Modem::addModemFactory(ModemOOK::factory, "OOK", 200000);
|
|
|
|
Modem::addModemFactory(ModemPSK::factory, "PSK", 200000);
|
|
|
|
Modem::addModemFactory(ModemQAM::factory, "QAM", 200000);
|
|
|
|
Modem::addModemFactory(ModemQPSK::factory, "QPSK", 200000);
|
|
|
|
Modem::addModemFactory(ModemSQAM::factory, "SQAM", 200000);
|
|
|
|
Modem::addModemFactory(ModemST::factory, "ST", 200000);
|
2015-11-22 19:56:25 -05:00
|
|
|
#endif
|
|
|
|
|
2015-07-21 00:04:04 -04:00
|
|
|
frequency = wxGetApp().getConfig()->getCenterFreq();
|
2015-01-06 00:57:57 -05:00
|
|
|
offset = 0;
|
2015-04-13 21:18:45 -04:00
|
|
|
ppm = 0;
|
2015-10-05 02:21:08 -04:00
|
|
|
devicesReady.store(false);
|
2016-01-13 21:59:47 -05:00
|
|
|
devicesFailed.store(false);
|
2015-10-05 02:21:08 -04:00
|
|
|
deviceSelectorOpen.store(false);
|
2014-11-23 19:39:27 -05:00
|
|
|
|
2015-07-30 19:30:46 -04:00
|
|
|
// Visual Data
|
2015-08-16 18:12:12 -04:00
|
|
|
spectrumVisualThread = new SpectrumVisualDataThread();
|
|
|
|
|
2015-07-30 20:36:06 -04:00
|
|
|
pipeIQVisualData = new DemodulatorThreadInputQueue();
|
|
|
|
pipeIQVisualData->set_max_num_items(1);
|
2015-08-03 01:38:38 -04:00
|
|
|
|
2015-08-11 00:50:43 -04:00
|
|
|
pipeWaterfallIQVisualData = new DemodulatorThreadInputQueue();
|
2015-09-10 23:42:22 -04:00
|
|
|
pipeWaterfallIQVisualData->set_max_num_items(128);
|
2015-08-03 01:38:38 -04:00
|
|
|
|
2015-10-17 16:17:12 -04:00
|
|
|
getSpectrumProcessor()->setInput(pipeIQVisualData);
|
2015-11-03 00:53:39 -05:00
|
|
|
getSpectrumProcessor()->setHideDC(true);
|
2015-07-30 19:30:46 -04:00
|
|
|
|
2015-08-01 11:03:00 -04:00
|
|
|
|
2015-07-30 19:30:46 -04:00
|
|
|
// I/Q Data
|
2015-08-12 21:45:02 -04:00
|
|
|
pipeSDRIQData = new SDRThreadIQDataQueue();
|
2015-08-16 18:12:12 -04:00
|
|
|
pipeSDRIQData->set_max_num_items(100);
|
2015-08-12 21:45:02 -04:00
|
|
|
|
2015-07-29 22:01:13 -04:00
|
|
|
sdrThread = new SDRThread();
|
2015-07-30 20:36:06 -04:00
|
|
|
sdrThread->setOutputQueue("IQDataOutput",pipeSDRIQData);
|
2014-11-23 19:39:27 -05:00
|
|
|
|
2014-11-29 13:58:20 -05:00
|
|
|
sdrPostThread = new SDRPostThread();
|
2015-07-30 20:36:06 -04:00
|
|
|
sdrPostThread->setInputQueue("IQDataInput", pipeSDRIQData);
|
2016-07-06 15:23:59 -04:00
|
|
|
|
2015-08-11 00:50:43 -04:00
|
|
|
sdrPostThread->setOutputQueue("IQVisualDataOutput", pipeIQVisualData);
|
|
|
|
sdrPostThread->setOutputQueue("IQDataOutput", pipeWaterfallIQVisualData);
|
2015-05-27 05:08:47 -04:00
|
|
|
|
2014-11-30 17:11:29 -05:00
|
|
|
t_PostSDR = new std::thread(&SDRPostThread::threadMain, sdrPostThread);
|
2015-08-16 18:12:12 -04:00
|
|
|
t_SpectrumVisual = new std::thread(&SpectrumVisualDataThread::threadMain, spectrumVisualThread);
|
2016-10-20 21:44:33 -04:00
|
|
|
|
|
|
|
#if CUBICSDR_ENABLE_VIEW_SCOPE
|
|
|
|
pipeAudioVisualData = new DemodulatorThreadOutputQueue();
|
|
|
|
pipeAudioVisualData->set_max_num_items(1);
|
|
|
|
|
|
|
|
scopeProcessor.setInput(pipeAudioVisualData);
|
|
|
|
#else
|
|
|
|
pipeAudioVisualData = nullptr;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if CUBICSDR_ENABLE_VIEW_DEMOD
|
|
|
|
demodVisualThread = new SpectrumVisualDataThread();
|
|
|
|
pipeDemodIQVisualData = new DemodulatorThreadInputQueue();
|
|
|
|
pipeDemodIQVisualData->set_max_num_items(1);
|
|
|
|
if (getDemodSpectrumProcessor()) getDemodSpectrumProcessor()->setInput(pipeDemodIQVisualData);
|
|
|
|
sdrPostThread->setOutputQueue("IQActiveDemodVisualDataOutput", pipeDemodIQVisualData);
|
2015-08-16 18:12:12 -04:00
|
|
|
t_DemodVisual = new std::thread(&SpectrumVisualDataThread::threadMain, demodVisualThread);
|
2016-10-20 21:44:33 -04:00
|
|
|
#else
|
|
|
|
demodVisualThread = nullptr;
|
|
|
|
pipeDemodIQVisualData = nullptr;
|
|
|
|
t_DemodVisual = nullptr;
|
|
|
|
#endif
|
|
|
|
|
2015-10-04 16:07:14 -04:00
|
|
|
sdrEnum = new SDREnumerator();
|
2016-01-22 00:40:00 -05:00
|
|
|
|
|
|
|
SDREnumerator::setManuals(config.getManualDevices());
|
2014-12-04 22:25:18 -05:00
|
|
|
|
2015-10-09 19:42:52 -04:00
|
|
|
appframe = new AppFrame();
|
2015-10-10 01:13:48 -04:00
|
|
|
t_SDREnum = new std::thread(&SDREnumerator::threadMain, sdrEnum);
|
2015-10-09 19:42:52 -04:00
|
|
|
|
2015-10-05 02:21:08 -04:00
|
|
|
//#ifdef __APPLE__
|
|
|
|
// int main_policy;
|
|
|
|
// struct sched_param main_param;
|
|
|
|
//
|
|
|
|
// main_policy = SCHED_RR;
|
|
|
|
// main_param.sched_priority = sched_get_priority_min(SCHED_RR)+2;
|
|
|
|
//
|
|
|
|
// pthread_setschedparam(pthread_self(), main_policy, &main_param);
|
|
|
|
//#endif
|
2014-12-04 22:25:18 -05:00
|
|
|
|
2014-10-27 20:05:40 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
int CubicSDR::OnExit() {
|
2016-02-16 01:13:26 -05:00
|
|
|
#if USE_HAMLIB
|
|
|
|
if (rigIsActive()) {
|
|
|
|
std::cout << "Terminating Rig thread.." << std::endl;
|
|
|
|
stopRig();
|
|
|
|
}
|
|
|
|
#endif
|
2016-07-05 15:43:45 -04:00
|
|
|
|
|
|
|
//The thread feeding them all should be terminated first, so:
|
2014-11-23 19:39:27 -05:00
|
|
|
std::cout << "Terminating SDR thread.." << std::endl;
|
2016-07-03 03:47:28 -04:00
|
|
|
sdrThread->terminate();
|
2016-07-05 15:43:45 -04:00
|
|
|
sdrThread->isTerminated(3000);
|
2016-07-03 03:47:28 -04:00
|
|
|
|
|
|
|
if (t_SDR) {
|
|
|
|
t_SDR->join();
|
2016-07-03 12:17:39 -04:00
|
|
|
delete t_SDR;
|
|
|
|
t_SDR = nullptr;
|
2015-10-03 21:35:11 -04:00
|
|
|
}
|
2016-07-05 15:43:45 -04:00
|
|
|
|
2014-11-30 17:11:29 -05:00
|
|
|
std::cout << "Terminating SDR post-processing thread.." << std::endl;
|
2014-11-29 13:58:20 -05:00
|
|
|
sdrPostThread->terminate();
|
2016-07-05 15:43:45 -04:00
|
|
|
|
|
|
|
std::cout << "Terminating All Demodulators.." << std::endl;
|
|
|
|
demodMgr.terminateAll();
|
|
|
|
|
2015-08-16 18:12:12 -04:00
|
|
|
std::cout << "Terminating Visual Processor threads.." << std::endl;
|
|
|
|
spectrumVisualThread->terminate();
|
2016-10-20 21:44:33 -04:00
|
|
|
if (demodVisualThread) {
|
|
|
|
demodVisualThread->terminate();
|
|
|
|
}
|
|
|
|
|
2016-07-03 03:47:28 -04:00
|
|
|
//Wait nicely
|
2016-06-28 15:04:52 -04:00
|
|
|
sdrPostThread->isTerminated(1000);
|
|
|
|
spectrumVisualThread->isTerminated(1000);
|
2016-10-20 21:44:33 -04:00
|
|
|
if (demodVisualThread) {
|
|
|
|
demodVisualThread->isTerminated(1000);
|
|
|
|
}
|
2016-06-28 15:04:52 -04:00
|
|
|
|
2016-07-03 03:47:28 -04:00
|
|
|
//Then join the thread themselves
|
|
|
|
t_PostSDR->join();
|
2016-10-20 21:44:33 -04:00
|
|
|
if (t_DemodVisual) t_DemodVisual->join();
|
2016-07-03 03:47:28 -04:00
|
|
|
t_SpectrumVisual->join();
|
|
|
|
|
|
|
|
//Now only we can delete
|
2014-11-23 19:39:27 -05:00
|
|
|
delete sdrThread;
|
2016-07-03 03:47:28 -04:00
|
|
|
sdrThread = nullptr;
|
2014-11-23 19:39:27 -05:00
|
|
|
|
2014-11-29 13:58:20 -05:00
|
|
|
delete sdrPostThread;
|
2016-07-03 03:47:28 -04:00
|
|
|
sdrPostThread = nullptr;
|
|
|
|
|
2014-11-30 17:11:29 -05:00
|
|
|
delete t_PostSDR;
|
2016-07-03 03:47:28 -04:00
|
|
|
t_PostSDR = nullptr;
|
2014-11-29 13:58:20 -05:00
|
|
|
|
2015-08-16 18:12:12 -04:00
|
|
|
delete t_SpectrumVisual;
|
2016-07-03 03:47:28 -04:00
|
|
|
t_SpectrumVisual = nullptr;
|
|
|
|
|
2015-08-16 18:12:12 -04:00
|
|
|
delete spectrumVisualThread;
|
2016-07-03 03:47:28 -04:00
|
|
|
spectrumVisualThread = nullptr;
|
|
|
|
|
2015-08-16 18:12:12 -04:00
|
|
|
delete t_DemodVisual;
|
2016-07-03 03:47:28 -04:00
|
|
|
t_DemodVisual = nullptr;
|
|
|
|
|
2015-08-16 18:12:12 -04:00
|
|
|
delete demodVisualThread;
|
2016-07-03 03:47:28 -04:00
|
|
|
demodVisualThread = nullptr;
|
2015-08-16 18:12:12 -04:00
|
|
|
|
2015-07-30 20:36:06 -04:00
|
|
|
delete pipeIQVisualData;
|
2016-07-03 03:47:28 -04:00
|
|
|
pipeIQVisualData = nullptr;
|
|
|
|
|
2015-07-30 20:36:06 -04:00
|
|
|
delete pipeAudioVisualData;
|
2016-07-03 03:47:28 -04:00
|
|
|
pipeAudioVisualData = nullptr;
|
|
|
|
|
2015-07-30 20:36:06 -04:00
|
|
|
delete pipeSDRIQData;
|
2016-07-03 03:47:28 -04:00
|
|
|
pipeSDRIQData = nullptr;
|
2014-11-29 13:58:20 -05:00
|
|
|
|
2014-11-23 19:39:27 -05:00
|
|
|
delete m_glContext;
|
2016-07-03 03:47:28 -04:00
|
|
|
m_glContext = nullptr;
|
2014-10-27 20:05:40 -04:00
|
|
|
|
2015-01-10 21:49:58 -05:00
|
|
|
#ifdef __APPLE__
|
|
|
|
AudioThread::deviceCleanup();
|
|
|
|
#endif
|
|
|
|
|
2014-10-27 20:05:40 -04:00
|
|
|
return wxApp::OnExit();
|
|
|
|
}
|
|
|
|
|
|
|
|
PrimaryGLContext& CubicSDR::GetContext(wxGLCanvas *canvas) {
|
|
|
|
PrimaryGLContext *glContext;
|
|
|
|
if (!m_glContext) {
|
2014-11-12 21:55:11 -05:00
|
|
|
m_glContext = new PrimaryGLContext(canvas, NULL);
|
2014-10-27 20:05:40 -04:00
|
|
|
}
|
|
|
|
glContext = m_glContext;
|
|
|
|
|
|
|
|
return *glContext;
|
|
|
|
}
|
|
|
|
|
2015-07-20 18:39:45 -04:00
|
|
|
void CubicSDR::OnInitCmdLine(wxCmdLineParser& parser) {
|
|
|
|
parser.SetDesc (commandLineInfo);
|
|
|
|
parser.SetSwitchChars (wxT("-"));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CubicSDR::OnCmdLineParsed(wxCmdLineParser& parser) {
|
|
|
|
wxString *confName = new wxString;
|
|
|
|
if (parser.Found("c",confName)) {
|
|
|
|
if (confName) {
|
|
|
|
config.setConfigName(confName->ToStdString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
config.load();
|
|
|
|
|
2015-11-08 16:45:06 -05:00
|
|
|
#ifdef BUNDLE_SOAPY_MODS
|
2015-11-10 19:25:41 -05:00
|
|
|
if (parser.Found("b")) {
|
2015-11-08 16:45:06 -05:00
|
|
|
useLocalMod.store(false);
|
2015-11-10 19:25:41 -05:00
|
|
|
} else {
|
|
|
|
useLocalMod.store(true);
|
2015-11-08 16:45:06 -05:00
|
|
|
}
|
|
|
|
#else
|
2015-11-10 19:25:41 -05:00
|
|
|
useLocalMod.store(true);
|
2015-11-08 16:45:06 -05:00
|
|
|
#endif
|
2015-11-12 18:38:38 -05:00
|
|
|
|
|
|
|
wxString *modPath = new wxString;
|
|
|
|
|
|
|
|
if (parser.Found("m",modPath)) {
|
|
|
|
if (modPath) {
|
|
|
|
modulePath = modPath->ToStdString();
|
|
|
|
} else {
|
|
|
|
modulePath = "";
|
|
|
|
}
|
|
|
|
}
|
2015-11-08 16:45:06 -05:00
|
|
|
|
2015-07-20 18:39:45 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-11-12 18:38:38 -05:00
|
|
|
void CubicSDR::closeDeviceSelector() {
|
|
|
|
if (deviceSelectorOpen) {
|
|
|
|
deviceSelectorDialog->Close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-04 16:07:14 -04:00
|
|
|
void CubicSDR::deviceSelector() {
|
2015-10-05 02:21:08 -04:00
|
|
|
if (deviceSelectorOpen) {
|
|
|
|
deviceSelectorDialog->Raise();
|
|
|
|
deviceSelectorDialog->SetFocus();
|
|
|
|
return;
|
2015-10-03 21:35:11 -04:00
|
|
|
}
|
2015-10-05 19:59:17 -04:00
|
|
|
deviceSelectorOpen.store(true);
|
2015-10-05 02:21:08 -04:00
|
|
|
deviceSelectorDialog = new SDRDevicesDialog(appframe);
|
|
|
|
deviceSelectorDialog->Show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CubicSDR::addRemote(std::string remoteAddr) {
|
|
|
|
SDREnumerator::addRemote(remoteAddr);
|
|
|
|
devicesReady.store(false);
|
|
|
|
t_SDREnum = new std::thread(&SDREnumerator::threadMain, sdrEnum);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CubicSDR::removeRemote(std::string remoteAddr) {
|
|
|
|
SDREnumerator::removeRemote(remoteAddr);
|
2015-10-03 21:35:11 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void CubicSDR::sdrThreadNotify(SDRThread::SDRThreadState state, std::string message) {
|
2016-06-02 17:56:31 -04:00
|
|
|
|
|
|
|
std::lock_guard < std::mutex > lock(notify_busy);
|
|
|
|
|
|
|
|
|
2015-11-03 21:06:22 -05:00
|
|
|
if (state == SDRThread::SDR_THREAD_INITIALIZED) {
|
|
|
|
appframe->initDeviceParams(getDevice());
|
|
|
|
}
|
2015-10-05 02:21:08 -04:00
|
|
|
if (state == SDRThread::SDR_THREAD_MESSAGE) {
|
|
|
|
notifyMessage = message;
|
|
|
|
}
|
2015-10-03 21:35:11 -04:00
|
|
|
if (state == SDRThread::SDR_THREAD_FAILED) {
|
2015-10-05 02:21:08 -04:00
|
|
|
notifyMessage = message;
|
|
|
|
// wxMessageDialog *info;
|
|
|
|
// info = new wxMessageDialog(NULL, message, wxT("Error initializing device"), wxOK | wxICON_ERROR);
|
|
|
|
// info->ShowModal();
|
2015-10-03 21:35:11 -04:00
|
|
|
}
|
2015-10-09 19:42:52 -04:00
|
|
|
//if (appframe) { appframe->SetStatusText(message); }
|
2016-06-02 17:56:31 -04:00
|
|
|
|
2015-10-03 21:35:11 -04:00
|
|
|
}
|
|
|
|
|
2015-10-04 16:07:14 -04:00
|
|
|
|
|
|
|
void CubicSDR::sdrEnumThreadNotify(SDREnumerator::SDREnumState state, std::string message) {
|
2016-06-02 17:56:31 -04:00
|
|
|
std::lock_guard < std::mutex > lock(notify_busy);
|
|
|
|
|
2015-10-05 02:21:08 -04:00
|
|
|
if (state == SDREnumerator::SDR_ENUM_MESSAGE) {
|
|
|
|
notifyMessage = message;
|
|
|
|
}
|
2015-10-04 16:07:14 -04:00
|
|
|
if (state == SDREnumerator::SDR_ENUM_DEVICES_READY) {
|
2015-10-05 02:21:08 -04:00
|
|
|
devs = SDREnumerator::enumerate_devices("", true);
|
|
|
|
devicesReady.store(true);
|
2015-10-04 16:07:14 -04:00
|
|
|
}
|
2016-01-13 21:59:47 -05:00
|
|
|
if (state == SDREnumerator::SDR_ENUM_FAILED) {
|
|
|
|
devicesFailed.store(true);
|
|
|
|
}
|
2015-10-09 19:42:52 -04:00
|
|
|
//if (appframe) { appframe->SetStatusText(message); }
|
2016-06-02 17:56:31 -04:00
|
|
|
|
2015-12-07 22:05:31 -05:00
|
|
|
|
2015-10-04 16:07:14 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-01-04 17:11:20 -05:00
|
|
|
void CubicSDR::setFrequency(long long freq) {
|
2015-01-11 17:08:16 -05:00
|
|
|
if (freq < sampleRate / 2) {
|
|
|
|
freq = sampleRate / 2;
|
2015-01-04 13:20:31 -05:00
|
|
|
}
|
2014-11-23 19:39:27 -05:00
|
|
|
frequency = freq;
|
2015-10-03 21:35:11 -04:00
|
|
|
sdrThread->setFrequency(freq);
|
2015-12-31 21:28:56 -05:00
|
|
|
getSpectrumProcessor()->setPeakHold(getSpectrumProcessor()->getPeakHold());
|
2016-06-09 13:33:52 -04:00
|
|
|
|
|
|
|
//make the peak hold act on the current dmod also, like a zoomed-in version.
|
2016-10-20 21:44:33 -04:00
|
|
|
if (getDemodSpectrumProcessor()) {
|
|
|
|
getDemodSpectrumProcessor()->setPeakHold(getSpectrumProcessor()->getPeakHold());
|
|
|
|
}
|
2014-11-23 19:39:27 -05:00
|
|
|
}
|
|
|
|
|
2015-01-06 00:57:57 -05:00
|
|
|
long long CubicSDR::getOffset() {
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CubicSDR::setOffset(long long ofs) {
|
|
|
|
offset = ofs;
|
2015-10-03 21:35:11 -04:00
|
|
|
sdrThread->setOffset(offset);
|
|
|
|
SDRDeviceInfo *dev = getDevice();
|
2015-07-08 01:07:39 -04:00
|
|
|
config.getDevice(dev->getDeviceId())->setOffset(ofs);
|
2015-01-06 00:57:57 -05:00
|
|
|
}
|
|
|
|
|
2015-01-04 17:11:20 -05:00
|
|
|
long long CubicSDR::getFrequency() {
|
2014-11-23 19:39:27 -05:00
|
|
|
return frequency;
|
2015-05-30 23:14:16 -04:00
|
|
|
}
|
|
|
|
|
2016-01-07 00:35:02 -05:00
|
|
|
|
|
|
|
void CubicSDR::lockFrequency(long long freq) {
|
|
|
|
frequency_locked.store(true);
|
|
|
|
lock_freq.store(freq);
|
|
|
|
|
|
|
|
if (sdrThread && !sdrThread->isTerminated()) {
|
|
|
|
sdrThread->lockFrequency(freq);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CubicSDR::isFrequencyLocked() {
|
|
|
|
return frequency_locked.load();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CubicSDR::unlockFrequency() {
|
|
|
|
frequency_locked.store(false);
|
|
|
|
sdrThread->unlockFrequency();
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:35:11 -04:00
|
|
|
void CubicSDR::setSampleRate(long long rate_in) {
|
|
|
|
sampleRate = rate_in;
|
|
|
|
sdrThread->setSampleRate(sampleRate);
|
|
|
|
setFrequency(frequency);
|
2015-12-29 20:52:49 -05:00
|
|
|
|
2015-12-30 03:24:35 -05:00
|
|
|
if (rate_in <= CHANNELIZER_RATE_MAX / 8) {
|
2015-12-29 23:44:00 -05:00
|
|
|
appframe->setMainWaterfallFFTSize(512);
|
|
|
|
appframe->getWaterfallDataThread()->getProcessor()->setHideDC(false);
|
|
|
|
spectrumVisualThread->getProcessor()->setHideDC(false);
|
|
|
|
} else if (rate_in <= CHANNELIZER_RATE_MAX) {
|
2015-12-29 20:52:49 -05:00
|
|
|
appframe->setMainWaterfallFFTSize(1024);
|
|
|
|
appframe->getWaterfallDataThread()->getProcessor()->setHideDC(false);
|
|
|
|
spectrumVisualThread->getProcessor()->setHideDC(false);
|
|
|
|
} else if (rate_in > CHANNELIZER_RATE_MAX) {
|
|
|
|
appframe->setMainWaterfallFFTSize(2048);
|
|
|
|
appframe->getWaterfallDataThread()->getProcessor()->setHideDC(true);
|
|
|
|
spectrumVisualThread->getProcessor()->setHideDC(true);
|
|
|
|
}
|
2015-05-30 23:14:16 -04:00
|
|
|
}
|
|
|
|
|
2016-07-05 15:43:45 -04:00
|
|
|
void CubicSDR::stopDevice(bool store, int waitMsForTermination) {
|
|
|
|
|
|
|
|
//Firt we must stop the threads
|
2016-07-03 03:47:28 -04:00
|
|
|
sdrThread->terminate();
|
2016-07-05 15:43:45 -04:00
|
|
|
sdrThread->isTerminated(waitMsForTermination);
|
2016-07-03 03:47:28 -04:00
|
|
|
|
|
|
|
if (t_SDR) {
|
|
|
|
t_SDR->join();
|
|
|
|
delete t_SDR;
|
|
|
|
t_SDR = nullptr;
|
2016-01-17 21:54:22 -05:00
|
|
|
}
|
2016-07-03 03:47:28 -04:00
|
|
|
|
2016-07-05 15:43:45 -04:00
|
|
|
//Only now we can nullify devices
|
|
|
|
if (store) {
|
|
|
|
stoppedDev = sdrThread->getDevice();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
stoppedDev = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
sdrThread->setDevice(nullptr);
|
2016-01-17 21:54:22 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void CubicSDR::reEnumerateDevices() {
|
|
|
|
devicesReady.store(false);
|
|
|
|
devs = nullptr;
|
|
|
|
SDREnumerator::reset();
|
|
|
|
t_SDREnum = new std::thread(&SDREnumerator::threadMain, sdrEnum);
|
|
|
|
}
|
|
|
|
|
2016-07-05 15:43:45 -04:00
|
|
|
void CubicSDR::setDevice(SDRDeviceInfo *dev, int waitMsForTermination) {
|
2016-07-03 03:47:28 -04:00
|
|
|
|
|
|
|
sdrThread->terminate();
|
2016-07-05 15:43:45 -04:00
|
|
|
sdrThread->isTerminated(waitMsForTermination);
|
2016-07-03 03:47:28 -04:00
|
|
|
|
|
|
|
if (t_SDR) {
|
|
|
|
t_SDR->join();
|
|
|
|
delete t_SDR;
|
|
|
|
t_SDR = nullptr;
|
2015-10-04 16:07:14 -04:00
|
|
|
}
|
2015-10-03 21:35:11 -04:00
|
|
|
|
2015-11-04 02:04:52 -05:00
|
|
|
for (SoapySDR::Kwargs::const_iterator i = settingArgs.begin(); i != settingArgs.end(); i++) {
|
|
|
|
sdrThread->writeSetting(i->first, i->second);
|
|
|
|
}
|
|
|
|
sdrThread->setStreamArgs(streamArgs);
|
2015-10-04 16:07:14 -04:00
|
|
|
sdrThread->setDevice(dev);
|
|
|
|
|
|
|
|
DeviceConfig *devConfig = config.getDevice(dev->getDeviceId());
|
|
|
|
|
2016-01-31 15:11:54 -05:00
|
|
|
SoapySDR::Device *soapyDev = dev->getSoapyDevice();
|
2015-10-04 19:55:52 -04:00
|
|
|
|
2016-01-31 15:11:54 -05:00
|
|
|
if (soapyDev) {
|
2016-05-11 22:37:25 -04:00
|
|
|
if (long devSampleRate = devConfig->getSampleRate()) {
|
|
|
|
sampleRate = dev->getSampleRateNear(SOAPY_SDR_RX, 0, devSampleRate);
|
|
|
|
sampleRateInitialized.store(true);
|
|
|
|
}
|
2015-10-04 19:55:52 -04:00
|
|
|
|
2015-10-21 16:56:32 -04:00
|
|
|
if (!sampleRateInitialized.load()) {
|
2016-01-31 15:11:54 -05:00
|
|
|
sampleRate = dev->getSampleRateNear(SOAPY_SDR_RX, 0, DEFAULT_SAMPLE_RATE);
|
2015-10-21 16:56:32 -04:00
|
|
|
sampleRateInitialized.store(true);
|
2016-01-31 15:11:54 -05:00
|
|
|
} else {
|
|
|
|
sampleRate = dev->getSampleRateNear(SOAPY_SDR_RX, 0, sampleRate);
|
2015-10-20 23:57:54 -04:00
|
|
|
}
|
|
|
|
|
2015-10-04 19:55:52 -04:00
|
|
|
if (frequency < sampleRate/2) {
|
|
|
|
frequency = sampleRate/2;
|
|
|
|
}
|
2016-01-31 15:11:54 -05:00
|
|
|
|
2015-10-04 19:55:52 -04:00
|
|
|
setFrequency(frequency);
|
|
|
|
setSampleRate(sampleRate);
|
|
|
|
|
|
|
|
setPPM(devConfig->getPPM());
|
|
|
|
setOffset(devConfig->getOffset());
|
2016-05-11 22:37:25 -04:00
|
|
|
|
|
|
|
|
|
|
|
if (devConfig->getAGCMode()) {
|
|
|
|
setAGCMode(true);
|
|
|
|
} else {
|
|
|
|
setAGCMode(false);
|
|
|
|
}
|
2016-01-31 15:11:54 -05:00
|
|
|
|
2015-10-04 19:55:52 -04:00
|
|
|
t_SDR = new std::thread(&SDRThread::threadMain, sdrThread);
|
2016-05-11 22:37:25 -04:00
|
|
|
}
|
2016-02-28 23:16:56 -05:00
|
|
|
|
|
|
|
stoppedDev = nullptr;
|
2015-05-31 22:13:14 -04:00
|
|
|
}
|
|
|
|
|
2015-10-03 21:35:11 -04:00
|
|
|
SDRDeviceInfo *CubicSDR::getDevice() {
|
2016-02-28 23:16:56 -05:00
|
|
|
if (!sdrThread->getDevice() && stoppedDev) {
|
|
|
|
return stoppedDev;
|
|
|
|
}
|
|
|
|
|
2015-10-03 21:35:11 -04:00
|
|
|
return sdrThread->getDevice();
|
2014-11-23 19:39:27 -05:00
|
|
|
}
|
2014-12-10 21:22:13 -05:00
|
|
|
|
2015-08-01 11:03:00 -04:00
|
|
|
ScopeVisualProcessor *CubicSDR::getScopeProcessor() {
|
|
|
|
return &scopeProcessor;
|
|
|
|
}
|
|
|
|
|
2015-08-16 18:12:12 -04:00
|
|
|
SpectrumVisualProcessor *CubicSDR::getSpectrumProcessor() {
|
|
|
|
return spectrumVisualThread->getProcessor();
|
2015-08-03 01:38:38 -04:00
|
|
|
}
|
|
|
|
|
2015-08-16 18:12:12 -04:00
|
|
|
SpectrumVisualProcessor *CubicSDR::getDemodSpectrumProcessor() {
|
2016-10-20 21:44:33 -04:00
|
|
|
if (demodVisualThread) {
|
|
|
|
return demodVisualThread->getProcessor();
|
|
|
|
} else {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2015-08-11 00:50:43 -04:00
|
|
|
}
|
|
|
|
|
2014-12-10 21:22:13 -05:00
|
|
|
DemodulatorThreadOutputQueue* CubicSDR::getAudioVisualQueue() {
|
2015-07-30 20:36:06 -04:00
|
|
|
return pipeAudioVisualData;
|
2014-12-10 21:22:13 -05:00
|
|
|
}
|
|
|
|
|
2014-12-26 16:15:35 -05:00
|
|
|
DemodulatorThreadInputQueue* CubicSDR::getIQVisualQueue() {
|
2015-07-30 20:36:06 -04:00
|
|
|
return pipeIQVisualData;
|
2014-12-10 21:22:13 -05:00
|
|
|
}
|
|
|
|
|
2015-08-11 00:50:43 -04:00
|
|
|
DemodulatorThreadInputQueue* CubicSDR::getWaterfallVisualQueue() {
|
|
|
|
return pipeWaterfallIQVisualData;
|
|
|
|
}
|
|
|
|
|
2014-12-10 21:22:13 -05:00
|
|
|
DemodulatorMgr &CubicSDR::getDemodMgr() {
|
|
|
|
return demodMgr;
|
|
|
|
}
|
|
|
|
|
2016-09-14 22:10:27 -04:00
|
|
|
BookmarkMgr &CubicSDR::getBookmarkMgr() {
|
|
|
|
return bookmarkMgr;
|
|
|
|
}
|
|
|
|
|
2015-10-18 12:26:07 -04:00
|
|
|
SDRPostThread *CubicSDR::getSDRPostThread() {
|
|
|
|
return sdrPostThread;
|
|
|
|
}
|
|
|
|
|
2015-11-03 21:06:22 -05:00
|
|
|
SDRThread *CubicSDR::getSDRThread() {
|
|
|
|
return sdrThread;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-12-10 21:22:13 -05:00
|
|
|
void CubicSDR::bindDemodulator(DemodulatorInstance *demod) {
|
|
|
|
if (!demod) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sdrPostThread->bindDemodulator(demod);
|
|
|
|
}
|
|
|
|
|
2016-05-31 19:58:37 -04:00
|
|
|
void CubicSDR::bindDemodulators(std::vector<DemodulatorInstance *> *demods) {
|
|
|
|
if (!demods) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sdrPostThread->bindDemodulators(demods);
|
|
|
|
}
|
|
|
|
|
2015-01-11 17:08:16 -05:00
|
|
|
long long CubicSDR::getSampleRate() {
|
|
|
|
return sampleRate;
|
|
|
|
}
|
|
|
|
|
2014-12-10 21:22:13 -05:00
|
|
|
void CubicSDR::removeDemodulator(DemodulatorInstance *demod) {
|
|
|
|
if (!demod) {
|
|
|
|
return;
|
|
|
|
}
|
2015-01-22 23:41:33 -05:00
|
|
|
demod->setActive(false);
|
2014-12-10 21:22:13 -05:00
|
|
|
sdrPostThread->removeDemodulator(demod);
|
2016-10-20 21:44:33 -04:00
|
|
|
wxGetApp().getAppFrame()->notifyUpdateModemProperties();
|
2014-12-10 21:22:13 -05:00
|
|
|
}
|
2015-01-12 00:40:43 -05:00
|
|
|
|
|
|
|
std::vector<SDRDeviceInfo*>* CubicSDR::getDevices() {
|
2015-09-13 22:18:29 -04:00
|
|
|
return devs;
|
2015-01-12 00:40:43 -05:00
|
|
|
}
|
2015-01-12 00:51:57 -05:00
|
|
|
|
2015-04-13 19:58:34 -04:00
|
|
|
|
|
|
|
AppConfig *CubicSDR::getConfig() {
|
|
|
|
return &config;
|
|
|
|
}
|
2015-04-13 21:18:45 -04:00
|
|
|
|
2015-04-22 22:54:48 -04:00
|
|
|
void CubicSDR::saveConfig() {
|
|
|
|
config.save();
|
|
|
|
}
|
|
|
|
|
2015-04-13 21:18:45 -04:00
|
|
|
void CubicSDR::setPPM(int ppm_in) {
|
|
|
|
ppm = ppm_in;
|
2015-10-03 21:35:11 -04:00
|
|
|
sdrThread->setPPM(ppm);
|
2015-04-13 21:18:45 -04:00
|
|
|
|
2015-10-03 21:35:11 -04:00
|
|
|
SDRDeviceInfo *dev = getDevice();
|
|
|
|
if (dev) {
|
|
|
|
config.getDevice(dev->getDeviceId())->setPPM(ppm_in);
|
|
|
|
}
|
2015-04-13 21:18:45 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
int CubicSDR::getPPM() {
|
2015-10-03 21:35:11 -04:00
|
|
|
SDRDeviceInfo *dev = sdrThread->getDevice();
|
|
|
|
if (dev) {
|
|
|
|
ppm = config.getDevice(dev->getDeviceId())->getPPM();
|
2015-04-13 21:18:45 -04:00
|
|
|
}
|
|
|
|
return ppm;
|
|
|
|
}
|
|
|
|
|
2016-02-07 19:32:05 -05:00
|
|
|
void CubicSDR::showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetMode, wxString initString) {
|
2015-08-14 20:19:37 -04:00
|
|
|
const wxString demodTitle("Set Demodulator Frequency");
|
|
|
|
const wxString freqTitle("Set Center Frequency");
|
2016-02-07 21:05:49 -05:00
|
|
|
const wxString bwTitle("Modem Bandwidth (150Hz - 500KHz)");
|
|
|
|
const wxString lpsTitle("Lines-Per-Second (1-1024)");
|
|
|
|
const wxString avgTitle("Average Rate (0.1 - 0.99)");
|
2016-02-07 22:19:05 -05:00
|
|
|
const wxString gainTitle("Gain Entry: "+wxGetApp().getActiveGainEntry());
|
2015-08-14 20:19:37 -04:00
|
|
|
|
|
|
|
wxString title;
|
|
|
|
|
|
|
|
switch (targetMode) {
|
|
|
|
case FrequencyDialog::FDIALOG_TARGET_DEFAULT:
|
2016-09-29 20:47:38 -04:00
|
|
|
case FrequencyDialog::FDIALOG_TARGET_FREQ:
|
2015-08-14 20:19:37 -04:00
|
|
|
title = demodMgr.getActiveDemodulator()?demodTitle:freqTitle;
|
|
|
|
break;
|
|
|
|
case FrequencyDialog::FDIALOG_TARGET_BANDWIDTH:
|
|
|
|
title = bwTitle;
|
|
|
|
break;
|
2016-02-07 21:05:49 -05:00
|
|
|
case FrequencyDialog::FDIALOG_TARGET_WATERFALL_LPS:
|
|
|
|
title = lpsTitle;
|
|
|
|
break;
|
|
|
|
case FrequencyDialog::FDIALOG_TARGET_SPECTRUM_AVG:
|
|
|
|
title = avgTitle;
|
|
|
|
break;
|
2016-02-07 22:19:05 -05:00
|
|
|
case FrequencyDialog::FDIALOG_TARGET_GAIN:
|
|
|
|
title = gainTitle;
|
|
|
|
if (wxGetApp().getActiveGainEntry() == "") {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
2015-08-14 20:19:37 -04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-02-07 21:05:49 -05:00
|
|
|
FrequencyDialog fdialog(appframe, -1, title, demodMgr.getActiveDemodulator(), wxPoint(-100,-100), wxSize(350, 75), wxDEFAULT_DIALOG_STYLE, targetMode, initString);
|
2015-05-10 01:39:10 -04:00
|
|
|
fdialog.ShowModal();
|
2015-05-04 19:44:03 -04:00
|
|
|
}
|
2015-05-10 01:39:10 -04:00
|
|
|
|
2016-06-11 04:08:12 -04:00
|
|
|
void CubicSDR::showLabelInput() {
|
|
|
|
|
|
|
|
DemodulatorInstance *activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator();
|
|
|
|
|
|
|
|
if (activeDemod != nullptr) {
|
|
|
|
|
2016-06-11 08:28:29 -04:00
|
|
|
const wxString demodTitle("Edit Demodulator label");
|
2016-06-11 04:08:12 -04:00
|
|
|
|
|
|
|
DemodLabelDialog labelDialog(appframe, -1, demodTitle, activeDemod, wxPoint(-100, -100), wxSize(500, 75), wxDEFAULT_DIALOG_STYLE);
|
|
|
|
labelDialog.ShowModal();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-08 21:32:15 -04:00
|
|
|
AppFrame *CubicSDR::getAppFrame() {
|
|
|
|
return appframe;
|
|
|
|
}
|
|
|
|
|
2015-05-10 21:43:03 -04:00
|
|
|
void CubicSDR::setFrequencySnap(int snap) {
|
|
|
|
if (snap > 1000000) {
|
|
|
|
snap = 1000000;
|
|
|
|
}
|
|
|
|
this->snap = snap;
|
|
|
|
}
|
|
|
|
|
|
|
|
int CubicSDR::getFrequencySnap() {
|
|
|
|
return snap;
|
|
|
|
}
|
2015-10-05 02:21:08 -04:00
|
|
|
|
|
|
|
bool CubicSDR::areDevicesReady() {
|
|
|
|
return devicesReady.load();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CubicSDR::areDevicesEnumerating() {
|
|
|
|
return !sdrEnum->isTerminated();
|
|
|
|
}
|
|
|
|
|
2016-01-13 21:59:47 -05:00
|
|
|
bool CubicSDR::areModulesMissing() {
|
|
|
|
return devicesFailed.load();
|
|
|
|
}
|
|
|
|
|
2015-10-05 02:21:08 -04:00
|
|
|
std::string CubicSDR::getNotification() {
|
|
|
|
std::string msg;
|
2016-06-02 17:56:31 -04:00
|
|
|
std::lock_guard < std::mutex > lock(notify_busy);
|
2015-10-05 02:21:08 -04:00
|
|
|
msg = notifyMessage;
|
2016-06-02 17:56:31 -04:00
|
|
|
|
2015-10-05 02:21:08 -04:00
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CubicSDR::setDeviceSelectorClosed() {
|
|
|
|
deviceSelectorOpen.store(false);
|
|
|
|
}
|
2015-10-10 01:13:48 -04:00
|
|
|
|
|
|
|
bool CubicSDR::isDeviceSelectorOpen() {
|
|
|
|
return deviceSelectorOpen.load();
|
|
|
|
}
|
2015-10-27 01:56:49 -04:00
|
|
|
|
|
|
|
void CubicSDR::setAGCMode(bool mode) {
|
|
|
|
agcMode.store(mode);
|
|
|
|
sdrThread->setAGCMode(mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CubicSDR::getAGCMode() {
|
|
|
|
return agcMode.load();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CubicSDR::setGain(std::string name, float gain_in) {
|
|
|
|
sdrThread->setGain(name,gain_in);
|
|
|
|
}
|
|
|
|
|
|
|
|
float CubicSDR::getGain(std::string name) {
|
|
|
|
return sdrThread->getGain(name);
|
|
|
|
}
|
|
|
|
|
2015-11-04 02:04:52 -05:00
|
|
|
void CubicSDR::setStreamArgs(SoapySDR::Kwargs streamArgs_in) {
|
|
|
|
streamArgs = streamArgs_in;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CubicSDR::setDeviceArgs(SoapySDR::Kwargs settingArgs_in) {
|
|
|
|
settingArgs = settingArgs_in;
|
|
|
|
}
|
|
|
|
|
2015-11-08 16:45:06 -05:00
|
|
|
bool CubicSDR::getUseLocalMod() {
|
|
|
|
return useLocalMod.load();
|
2015-11-12 18:38:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string CubicSDR::getModulePath() {
|
|
|
|
return modulePath;
|
|
|
|
}
|
2016-01-03 19:00:26 -05:00
|
|
|
|
2016-02-07 22:19:05 -05:00
|
|
|
void CubicSDR::setActiveGainEntry(std::string gainName) {
|
|
|
|
activeGain = gainName;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string CubicSDR::getActiveGainEntry() {
|
|
|
|
return activeGain;
|
|
|
|
}
|
|
|
|
|
2016-02-11 01:09:15 -05:00
|
|
|
void CubicSDR::setSoloMode(bool solo) {
|
|
|
|
soloMode.store(solo);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CubicSDR::getSoloMode() {
|
|
|
|
return soloMode.load();
|
|
|
|
}
|
|
|
|
|
2016-02-07 18:01:11 -05:00
|
|
|
int CubicSDR::FilterEvent(wxEvent& event) {
|
|
|
|
if (!appframe) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-03-03 20:41:28 -05:00
|
|
|
if (event.GetEventType() == wxEVT_KEY_DOWN || event.GetEventType() == wxEVT_CHAR_HOOK) {
|
|
|
|
return appframe->OnGlobalKeyDown((wxKeyEvent&)event);
|
2016-02-07 18:01:11 -05:00
|
|
|
}
|
|
|
|
|
2016-03-03 20:41:28 -05:00
|
|
|
if (event.GetEventType() == wxEVT_KEY_UP || event.GetEventType() == wxEVT_CHAR_HOOK) {
|
2016-02-07 18:01:11 -05:00
|
|
|
return appframe->OnGlobalKeyUp((wxKeyEvent&)event);
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1; // process normally
|
|
|
|
}
|
|
|
|
|
2016-01-03 19:00:26 -05:00
|
|
|
#ifdef USE_HAMLIB
|
|
|
|
RigThread *CubicSDR::getRigThread() {
|
|
|
|
return rigThread;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CubicSDR::initRig(int rigModel, std::string rigPort, int rigSerialRate) {
|
|
|
|
if (rigThread) {
|
2016-07-03 03:47:28 -04:00
|
|
|
|
|
|
|
rigThread->terminate();
|
|
|
|
rigThread->isTerminated(1000);
|
2016-01-03 19:00:26 -05:00
|
|
|
}
|
2016-07-03 03:47:28 -04:00
|
|
|
|
2016-01-03 19:00:26 -05:00
|
|
|
if (t_Rig && t_Rig->joinable()) {
|
|
|
|
t_Rig->join();
|
2016-07-03 03:47:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
//now we can delete
|
|
|
|
if (rigThread) {
|
|
|
|
|
|
|
|
delete rigThread;
|
|
|
|
rigThread = nullptr;
|
|
|
|
}
|
|
|
|
if (t_Rig) {
|
|
|
|
|
2016-01-03 19:00:26 -05:00
|
|
|
delete t_Rig;
|
|
|
|
t_Rig = nullptr;
|
|
|
|
}
|
2016-07-03 03:47:28 -04:00
|
|
|
|
2016-01-03 19:00:26 -05:00
|
|
|
rigThread = new RigThread();
|
|
|
|
rigThread->initRig(rigModel, rigPort, rigSerialRate);
|
2016-02-16 01:13:26 -05:00
|
|
|
rigThread->setControlMode(wxGetApp().getConfig()->getRigControlMode());
|
|
|
|
rigThread->setFollowMode(wxGetApp().getConfig()->getRigFollowMode());
|
2016-02-29 23:14:23 -05:00
|
|
|
rigThread->setCenterLock(wxGetApp().getConfig()->getRigCenterLock());
|
|
|
|
rigThread->setFollowModem(wxGetApp().getConfig()->getRigFollowModem());
|
2016-02-16 01:13:26 -05:00
|
|
|
|
2016-01-03 19:00:26 -05:00
|
|
|
t_Rig = new std::thread(&RigThread::threadMain, rigThread);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CubicSDR::stopRig() {
|
|
|
|
if (!rigThread) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rigThread) {
|
2016-07-03 03:47:28 -04:00
|
|
|
|
|
|
|
rigThread->terminate();
|
|
|
|
rigThread->isTerminated(1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (t_Rig && t_Rig->joinable()) {
|
|
|
|
t_Rig->join();
|
|
|
|
}
|
|
|
|
|
|
|
|
//now we can delete
|
|
|
|
if (rigThread) {
|
|
|
|
|
2016-01-03 19:00:26 -05:00
|
|
|
delete rigThread;
|
|
|
|
rigThread = nullptr;
|
|
|
|
}
|
2016-07-03 03:47:28 -04:00
|
|
|
|
|
|
|
if (t_Rig) {
|
|
|
|
|
2016-01-03 19:00:26 -05:00
|
|
|
delete t_Rig;
|
|
|
|
t_Rig = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CubicSDR::rigIsActive() {
|
|
|
|
return (rigThread && !rigThread->isTerminated());
|
|
|
|
}
|
|
|
|
|
2016-01-28 15:49:31 -05:00
|
|
|
#endif
|